The following roles are categorized into two types, ordinary users and administrator users, at least for ordinary users, direct modification of the DB is not desirable, to have the function of user registration, the following is the beginning of the development of user registration.
user interface
First of all, think about what information the user needs to provide when registering: username, password, nickname, e-mail, birthday, gender, self-introduction, and modify the user model according to this information below:
class User(): __tablename__="users" id=(,primary_key=True) username=((50),unique=True,index=True) password=((50)) nickname=((50)) email=((100)) birthday=() gender=() remark=((200)) role_id=(,(""))
Then use the script to modify the db
python db migrate -m "Modify user table"
Enter and the interface displays the contents:
Then make the db difference changes
python db upgrade
At this point look at the table structure in the db:
Modified successfully.
registration screen
Then create a new template and set up the login form:
{% extends ""%} {% block content %} <!--concrete content--> <div class="container"> <div class="row"></div> <div class="row"> <div> <div class="page-header"> <h1>Welcome to register</h1> </div> {% for message in get_flashed_messages() %} <div class="alert alert-warning"> <button type="button" class="close" data-dismiss="alter">×</button> {{message}} </div> {% endfor %} <form method="post"> <div class="form-group"> <label for="username">user ID</label> <input type="text" class="form-control" name="username" placeholder="Please enter your user name."> </div> <div class="form-group"> <label for="passworld">cryptographic</label> <input type="password" class="form-control" name="password" placeholder="Please enter the password."> </div> <div class="form-group"> <label for="email">term of endearment</label> <input type="email" class="form-control" name="nickname" placeholder="Please enter a nickname."> </div> <div class="form-group"> <label for="birthday">birthdays</label> <input type="date" class="form-control" name="birthday" placeholder="Please enter your birthday."> </div> <div class="form-group"> <label >distinguishing between the sexes</label> <label class="form-control"> <input type="radio" name="gender" value="0" ><label for="gender0">male</label> <input type="radio" name="gender" value="1" ><label for="gender1">women</label> </label> </div> <div class="form-group"> <label for="email">e-mail address</label> <input type="email" class="form-control" name="email" placeholder="Please enter your e-mail address."> </div> <button type="submit" class="btn btn-default">log in</button> </form> </div> </div> </div> {% endblock %}
Then add a new REGISTER route to the file with the code:
@("/register",methods=["GET"]) def register(): return render_template("/")
Run the interface as normal and then add post routing:
@("/register",methods=["Post"]) def registerPost(): user=User(); =("username","") = ("password", "") = ("birthday", "") = ("email", "") = ("gender", "") = ("nickname", "") user.role_id = 1 #Temporarily agree that the public user role is 1 #Judgement, where username, password, nickname can not be empty if(len(())==0): flash("User name cannot be empty.") return render_template("/") if(len(())==0): flash("User password cannot be empty.") return render_template("/") if (len(()) == 0): flash("User nicknames cannot be empty.") return render_template("/") (user); flash("You have been successfully registered.") return render_template("/")
The code is a bit wordy, not beautiful, but the basic intent can be expressed clearly, the function can also be realized, but now the problem comes, join me to add a new field, then need to modify the code in three places (html,, check), and especially need to modify the html, and the html part of the validation is not available, if you add client-side validation, then you need to modify the will be more. So there is no one for the form to optimize the tool it , the answer is of course there , it is the turn of wtf debut .
Introducing the WTF Forms Framework
As before, the plugin needs to be installed first.
pip3.6 install flask-wtf
Then introduce the required packages
from import Form from wtforms import StringField,PasswordField,SubmitField,RadioField from import DataRequired,EqualTo,Length
The following creates a form RegisterForm.
class RegisterForm(Form): username = StringField("Please enter your user name.", validators=[DataRequired()]) password = PasswordField("Please enter the password.", validators=[DataRequired()]) repassword=PasswordField("Confirm password", validators=[EqualTo("password")]) nickname= StringField("Nickname.") birthday= DateField("Date of birth") email= StringField("E-mail address", validators=[Email()]) gender= RadioField("Gender", choices=[("0", "Male."), ("1", "Female.")], default=0) remark= TextAreaField("Self-Introduction") submit=SubmitField("Submit")
Modify the template:
{% extends ""%} {% block content %} <!--concrete content--> {% import "bootstrap/" as wtf %} <!--import (data)bootstrap(architecture) formwork --> <div class="container"> <div class="row"></div> <div class="row"> <div> <div class="page-header"> <h1>Welcome to register</h1> </div> {% for message in get_flashed_messages() %} <div class="alert alert-warning"> <button type="button" class="close" data-dismiss="alter">×</button> {{message}} </div> {% endfor %} {{ wtf.quick_form(form)}} <!--Creating Forms--> </div> </div> </div> {% endblock %}
Execute and output the result:
Ao, it reported an error, see what error is output:
Note the red line, is a CSRF error, the concept of CSRF can be directly Baidu, know the problem, in fact, it is also very good to modify, in the framework of the increase of a secret key can be effective in preventing the increase of a line in the:
['SECRET_KEY'] = "Niu_blog String"
Customizable secret key string
Then run it again and the interface appears:
And include validation bootstrap validation style, next continue to transform has completed this registration function
@("/register",methods=["GET","POST"]) def register(): form=RegisterForm() if form.validate_on_submit(): user=User() = = = = = = user.role_id=1 #Temporarily agree that the public user role is 1 (user) return render_template("/",form=form)
Note that the registerPost method has been removed at this point.
Well, run a test.
Click to submit.
Ao, what's wrong with the date format? That's something to look at in the source code:
class DateField(DateTimeField): """ Same as DateTimeField, except stores a ``. """ def __init__(self, label=None, validators=None, format='%Y-%m-%d', **kwargs): super(DateField, self).__init__(label, validators, format, **kwargs) def process_formdata(self, valuelist): if valuelist: date_str = ' '.join(valuelist) try: = (date_str, ).date() except ValueError: = None raise ValueError(('Not a valid date value'))
This is the source code of wtforms field, located in /wtforms/fields/ line 745, you can see that the date format supported here is year-month-day format, the format is limited to a relatively dead, and the text box does not use html5 date but ordinary text, the solution will be said later, for the time being, first modify the input, change to 1988-2-5 and then click submit:
Note that since the code still returns to this page after a successful submit and injects content, there is no problem displaying it, look in the db:
The record enters the db normally and the function realization is complete.
Improvements to the login page
The login page is remodeled below, starting with the creation of the login form:
class LoginForm(Form): username=StringField("Please enter your user name.",validators=[DataRequired()]) password=PasswordField("Please enter the password.") submit=SubmitField("Login")
Modify the login template page:
{% extends ""%} {% import "bootstrap/" as wtf %} {% block content %} <!--concrete content--> <div class="container"> <div class="row"></div> <div class="row"> <div class="col-md-4 col-md-offset-4 col-sm-6 col-sm-offset-3"> <div class="page-header"> <h1>Welcome</h1> </div> {% for message in get_flashed_messages() %} <div class="alert alert-warning"> <button type="button" class="close" data-dismiss="alter">×</button> {{message}} </div> {% endfor %} {{ wtf.quick_form(form)}} </div> </div> </div> {% endblock %}
Modify the routing method:
@("/login",methods=["GET","POST"]) def login(): form=LoginForm() if form.validate_on_submit(): username = password = user = .filter_by(username=username, password=password).first() if user is not None: session["user"] = username return render_template("/", name=username, site_name='myblog') else: flash("The username or password you entered is incorrect.") return render_template("/",form=form) # Returned is still the login page return render_template("/",form=form)
Restart the service, run the program, enter zhangji and 123, successfully logged into the home page!
Back to home page
Right now the home page is blank, with no content whatsoever. A normal light blog should log in and show the post button, followed posts, etc., but first the logged in status has to be recorded, and these will be explained in the next chapter.
This is the whole content of this article.