Add more clear paths informations
parent
2dde04cb65
commit
1e524e95bf
1 changed files with 29 additions and 28 deletions
|
|
@ -28,45 +28,46 @@ WTF (What the Form) Provides a easy way to handle user's data submission.
|
|||
# Overview
|
||||
Ok, so from now, we should have all the libs ready. Here the folder structures:
|
||||
|
||||
config.py
|
||||
run.py
|
||||
shell.py
|
||||
app.db
|
||||
app/__init__.py
|
||||
app/constants.py
|
||||
app/static/
|
||||
/config.py
|
||||
/run.py
|
||||
/shell.py
|
||||
/app.db
|
||||
/app/__init__.py
|
||||
/app/constants.py
|
||||
/app/static/
|
||||
|
||||
For every module (or sub app... ) well have this file structure (here for the users module)
|
||||
|
||||
app/users/__init__.py
|
||||
app/users/views.py
|
||||
app/users/forms.py
|
||||
app/users/constants.py
|
||||
app/users/models.py
|
||||
app/users/decorators.py
|
||||
/app/users/__init__.py
|
||||
/app/users/views.py
|
||||
/app/users/forms.py
|
||||
/app/users/constants.py
|
||||
/app/users/models.py
|
||||
/app/users/decorators.py
|
||||
|
||||
for every module that need templating (jinja) we store those in the templates folder + module directory.
|
||||
|
||||
app/templates/404.html
|
||||
app/templates/users/login.html
|
||||
app/templates/users/register.html
|
||||
/app/templates/404.html
|
||||
/app/templates/base.html
|
||||
/app/templates/users/login.html
|
||||
/app/templates/users/register.html
|
||||
...
|
||||
|
||||
for the static file you should serve them with a dedicated http server, but being in at a dev stage, we'll let flask serve them. Flask will automagically serve static files from this static folder. If you want to use another folder... you can read about that here: http://flask.pocoo.org/docs/api/#application-object
|
||||
|
||||
app/static/js/main.js
|
||||
app/static/css/reset.css
|
||||
app/static/img/header.png
|
||||
/app/static/js/main.js
|
||||
/app/static/css/reset.css
|
||||
/app/static/img/header.png
|
||||
|
||||
We'll create 4 modules, a user module (manage user's registration, login, password lost, profile edit and maybe Third party Login/Registration) an emails module intended to be used by a queuing server, and a posts and comments modules
|
||||
|
||||
## Config
|
||||
`run.py` will be used to launch the web server.
|
||||
`/run.py` will be used to launch the web server.
|
||||
|
||||
from tol import app
|
||||
app.run(debug=True)
|
||||
|
||||
`shell.py` will allow you to get a console and enter commands within your flask environment. Maybe not as nice as debugging with pdb, but always usefull (when you will initialize your database)
|
||||
`/shell.py` will allow you to get a console and enter commands within your flask environment. Maybe not as nice as debugging with pdb, but always usefull (when you will initialize your database)
|
||||
|
||||
#!/usr/bin/env python
|
||||
import os
|
||||
|
|
@ -78,7 +79,7 @@ We'll create 4 modules, a user module (manage user's registration, login, passwo
|
|||
|
||||
os.environ['PYTHONINSPECT'] = 'True'
|
||||
|
||||
`config.py` will be storing all the module configurations. Here, the database is setup to use SQLite, because it's a very convenient dev env database. Most likely `config.py` won't be a part of your repository and will be different on your test and production servers.
|
||||
`/config.py` will be storing all the module configurations. Here, the database is setup to use SQLite, because it's a very convenient dev env database. Most likely `/config.py` won't be a part of your repository and will be different on your test and production servers.
|
||||
|
||||
import os
|
||||
_basedir = os.path.abspath(os.path.dirname(__file__))
|
||||
|
|
@ -115,8 +116,8 @@ We'll create 4 modules, a user module (manage user's registration, login, passwo
|
|||
## First module
|
||||
We'll start with the users modules. In order, we'll define the models, the constants linked to this model, the form and finally the first view and it's template.
|
||||
|
||||
### First model (and it's constants.py)
|
||||
The `models.py`
|
||||
### First model (and it's constants file)
|
||||
The `/app/users/models.py`
|
||||
|
||||
from app import db
|
||||
from app.users import constants as USER
|
||||
|
|
@ -145,7 +146,7 @@ The `models.py`
|
|||
def __repr__(self):
|
||||
return '<User %r>' % (self.name)
|
||||
|
||||
and it's constants in the `constants.py` file:
|
||||
and it's constants in the `/app/users/constants.py` file:
|
||||
|
||||
# User role
|
||||
ADMIN = 0
|
||||
|
|
@ -171,7 +172,7 @@ First about the constants file, I like to have my constants their own file and
|
|||
|
||||
### First form
|
||||
|
||||
Now that we've done our object model, time to build the form that goes with it. We'll start with a registration and login form. The registration form will request the user's name, email and password. We'll use validators to ensure the user submitted correct values. Finally, a Repcaptcha field (provided by flask) will avoid machine registration. Just in case you plan on having Term of Service, I added a BooleanField called accept_tos. Since this field is required, the user will have to check the checkbox generated by this field on the box. The login form will have only email and password with the same validators.
|
||||
Now that we've done our object model, time to build the form that goes with it. We'll start with a registration and login form. The registration form will request the user's name, email and password. We'll use validators to ensure the user submitted correct values. Finally, a Repcaptcha field (provided by flask) will avoid machine registration. Just in case you plan on having Term of Service, I added a BooleanField called accept_tos. Since this field is required, the user will have to check the checkbox generated by this field on the box. The login form will have only email and password with the same validators. Here's the '/app/users/forms.py' file:
|
||||
|
||||
from flaskext.wtf import Form, TextField, PasswordField, BooleanField, RecaptchaField
|
||||
from flaskext.wtf import Required, Email, EqualTo
|
||||
|
|
@ -197,7 +198,7 @@ Form more details of what can be done with WTF check [http://wtforms.simplecodes
|
|||
|
||||
### First view
|
||||
|
||||
The view is where we'll declare our Blueprint. Using url_prefix will prefix every url you set using route. A nice feature from WTF-Flask is the form.validate_on_submit: it check that the current request is POST and that the form validates. Once the user is logged in we want to redirect the user to his profile (/users/me/), method that is we will have to protect with a decorator:
|
||||
The view is where we'll declare our Blueprint. Using url_prefix will prefix every url you set using route. A nice feature from WTF-Flask is the form.validate_on_submit: it check that the current request is POST and that the form validates. Once the user is logged in we want to redirect the user to his profile (/users/me/), method that is we will have to protect with a decorator (`/app/users/decorators.py`):
|
||||
|
||||
from functools import wraps
|
||||
|
||||
|
|
@ -212,7 +213,7 @@ The view is where we'll declare our Blueprint. Using url_prefix will prefix ever
|
|||
return f(*args, **kwargs)
|
||||
return decorated_function
|
||||
|
||||
This decorator is checking that g.user has a value assigned to it, otherwise it means that the user isn't authenticated, we then add a message to be displayed to the user on the next page and redirect him to the login view. You probably wonder how `g.user` get defined, it's in the user's `views.py`, through the `before_request`. You'll realize later that if you pull a lot of information from your user's profile (historical data, friends, messages, activities...) this might become a bottle neck and caching user through their id might be a good solution (as long as you centralize your object modifications and clear this cache on every update).
|
||||
This decorator is checking that g.user has a value assigned to it, otherwise it means that the user isn't authenticated, we then add a message to be displayed to the user on the next page and redirect him to the login view. You probably wonder how `g.user` get defined, it's in the user's `views.py`, through the `before_request`. You'll realize later that if you pull a lot of information from your user's profile (historical data, friends, messages, activities...) this might become a bottle neck and caching user through their id might be a good solution (as long as you centralize your object modifications and clear this cache on every update). Following are the views definition in `/app/users/views.py`:
|
||||
|
||||
from flask import Blueprint, request, render_template, flash, g, session, redirect, url_for
|
||||
from werkzeug import check_password_hash, generate_password_hash
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue