Python Flask framework implements the logon user profile and profile tutorial, pythonflask
User Information Page
On the user information page, there are basically no new concepts that must be emphasized and introduced. You only need to create a new view function template page containing HTML.
The following is a view function (project directory/views. py ):
@ App. route ('/user/<nickname>') @ login_requireddef user (nickname): user = User. query. filter_by (nickname = nickname ). first () if user = None: flash ('nonexistent user: '+ nickname + '! ') Return redirect (url_for ('index') posts = [{'author': user, 'body': 'test post # 1'}, {'author ': user, 'body': 'test post # 2'}] return render_template('user.html ', user = user, posts = posts)
Here the @ app. route identifier is mainly used to indicate that this view function is different from the previous ones. We have defined a parameter named <nickname>. In the function, it is converted to a parameter with the same name as it. When a user requests a URL such as URL/user/miguel, the sub-view function recognizes that there is a parameter named nickname with the value of 'miguel', that is, nickname = 'miguel '.
There is no need to be surprised by the implementation process of this method. First, we need to use the converted nickname parameter as a condition to try to call the user data from the database. If no data is found, we will give you an error message and jump to the homepage as before.
Once we find the modified user, we will display the user's article under the template. Note that only the user's article is displayed on the user information page, so the author of the article is the user.
The initialized view template is very simple (project directory/templates/user.html ):
<! -- Extend base layout -- >{% extends "base.html" %}{% block content %}< h1> user nickname: {user. nickname }}! </H1>
The user information page is ready, but there is no link to the changed page on the site. To make it easy for users to view their own information, we put the link address on the top navigation (project directory/templates/base.html ):
<Div> Microblog: <a href = "{url_for ('index') }}"> Home </a> {% if g. user. is_authenticated () %} | <a href = "{url_for ('user', nickname = g. user. nickname) }}"> your profile </a> | <a href = "{url_for ('logout ')}} "> log out </a >{% endif %}</div>
Note that we have passed parameters to the function and the previous URL.
Now let's try this project. Click "your profile" to go to the user profile page. Since we have not yet pointed to a link address for the casual user information page, if you want to see other people's information here, you need to manually enter the address. For example, if you want to view miguel information, the address is: http: // localhost: 5000/user/miguelt.
Profile picture
I believe you will think that the current user information page looks monotonous. To be nice, we will add the user avatar function.
To avoid the need for our server to process a large number of uploaded avatar images, we can use Gravatar here to provide our users with user portraits.
Since the returned user profile picture belongs to the user, we put the code in theUserclass (project directory/models. py ):
from hashlib import md5# ...class User(db.Model): # ... def avatar(self, size): return 'http://www.gravatar.com/avatar/' + md5(self.email).hexdigest() + '?d=mm&s=' + str(size)
Avatar will return the address of the user's profile picture and request the size pixel of the picture you want based on your needs.
It is easy to get an image from Gravatar. You only need to use md5 to encrypt the user's mailbox hash and merge it into the above url format. You can also customize the image size. "D = mm" indicates the default profile picture displayed by the user without the Gravatar account. The "mm" option returns a gray image with only a person profile, which is called a "mysterious person ". The "s =" option is used to set the returned image size pixel.
Of course, Gravatar also has its own documentation to describe URL splicing technology!
Here, Userclass can return an image of a user's profile. We need to integrate this into the user profile layout (project directory/templates/user.html ):
<! -- Extend base layout -- >{% extends "base.html" %}{% block content %}< table> <tr valign = "top"> <td> </td>
The highlight of designing Userclass to return the user's profile picture is: if one day we think the profile picture on the Gravatar website is not what we want, we only need to rewrite the Avatar processing function to return the desired address (even if someone leeching points to our server, we can protect our host ), in this way, you only need to modify this point, so the template is still running automatically.
We have added the user profile picture to the top of the user profile details page, but at the bottom of the page we have not shown the article, we also need to show the user profile picture before the article. However, on the user profile page, you need to display the same profile picture for all the articles, but it would be nice to move the profile picture function to the home page to show the author's profile picture for all the articles.
We only need to slightly modify the template file to display the Corresponding author's profile (project directory/templates/user.html) to the article ):
<! -- Extend base layout -- >{% extends "base.html" %}{% block content %}< table> <tr valign = "top"> <td> </td>
This is our user information page so far:
Microblog user details page
Reuse sub-template
The user information page displays the user's own articles, but the homepage of the website needs to display different user articles at the moment. Here there are two template files used to display User articles. We can directly copy and paste the code that processes the displayed article and paste it directly to the new template. In fact, this is not the best method. If one day we need to modify the display article, we need to update the template files that contain the document display code.
Instead, we will create a new sub-template file to process the article display function, and then include this file when you need to display the article.
At the beginning, we will create a child empty template file and copy the code that shows the article on the user information page (project directory/templates/post.html ):
<Table> <tr valign = "top"> <td> </td> <I >{{ post. author. nickname }}released: </I> <br >{{ post. body }}</td> </tr> </table>
Then, use the Jinja2 inclusion function to call the sub-template file (project directory/templates/user.html)
<! -- Extend base layout -- >{% extends "base.html" %}{% block content %}< table> <tr valign = "top"> <td> </td>
Once we have a complete page, we can follow the above method to call the next sub-template to display the article, but now we are not in a hurry, we will talk about it in the subsequent chapter of the tutorial.
More personal information
Although the user information page is relatively precise, there is still a lot of information not displayed. Most users prefer to display more information on their websites, so we can allow users to enter their own information here. Of course, we can also record the time when users log on to this site each time and display their own information details page.
To display more information, we need to update the database. Add a new field (project directory/models. py) to Userclass ):
class User(db.Model): id = db.Column(db.Integer, primary_key = True) nickname = db.Column(db.String(64), unique = True) email = db.Column(db.String(120), index = True, unique = True) role = db.Column(db.SmallInteger, default = ROLE_USER) posts = db.relationship('Post', backref = 'author', lazy = 'dynamic') about_me = db.Column(db.String(140)) last_seen = db.Column(db.DateTime)
Every time we modify the database, we need to generate a new record (migration ). Note that we should remember to create a migration when processing data updates to the database. Now let's look at the final result. We only need the following code to update the two newly added fields to the database:
./db_migrate.py
Of course, the corresponding response script is
New migration saved as db_repository/versions/003_migration.pyCurrent database version: 3
Now the two newly added fields are saved to the database. However, it is a bit different to call this script in the window system.
If data migration is not supported, you must manually modify the database. Otherwise, you must delete the database and create data again from the beginning.
Next, we need to modify the user details page to display the newly added field (project directory/templates/user.html ):
<! -- Extend base layout -- >{% extends "base.html" %}{% block content %}< table> <tr valign = "top"> <td> </td>
Because we only need to display these two fields when you fill them out, we can use the Jinja2 judgment condition to display these fields.
For all users, the two fields are empty and nothing is displayed.
The last field (last_seen) is particularly well processed. Note that we have set the parameters for receiving user requests (flask. g and global, asg. user. That is, you need to record the user's logon time (project directory/views. py) in this optimal segment ):
from datetime import datetime# ...@app.before_requestdef before_request(): g.user = current_user if g.user.is_authenticated(): g.user.last_seen = datetime.utcnow() db.session.add(g.user) db.session.commit()
If you log on, the last logon time will be displayed on the data details page. Of course, the corresponding logon time will be automatically updated every time you refresh the page. This is because when the browser does not refresh once, it will request the received parameters set above and update the database's processing functions.
Here we record the International Standard Time UTC time zone. In the previous chapter, we also mentioned how to store a timestamp suitable for all time zones. This will have a negative error message, because the time zone of UTC is displayed on the data page of all users, I will explain this problem in detail in the following section about the time and date.
To display more information about users, we have to give them a link, which is best suited for editing the user information page.
Edit user details
It's really easy to create a user data editing page. You just need to create the following web form (project directory/forms. py ):
from flask.ext.wtf import Form, TextField, BooleanField, TextAreaFieldfrom flask.ext.wtf import Required, Length class EditForm(Form): nickname = TextField('nickname', validators = [Required()]) about_me = TextAreaField('about_me', validators = [Length(min = 0, max = 140)])
View template file (project directory/templates/edit.html ):
<! -- Extend base layout -- >{% extends "base.html" %}{% block content %}< h1> Edit Your Profile
The last step is to create a view (project directory/views. py ):
from forms import LoginForm, EditForm @app.route('/edit', methods = ['GET', 'POST'])@login_requireddef edit(): form = EditForm() if form.validate_on_submit(): g.user.nickname = form.nickname.data g.user.about_me = form.about_me.data db.session.add(g.user) db.session.commit() flash('Your changes have been saved.') return redirect(url_for('edit')) else: form.nickname.data = g.user.nickname form.about_me.data = g.user.about_me return render_template('edit.html', form = form)
To facilitate user editing, we need to add a link address (project directory/templates/user.html) to the user's personal data page ):
<! -- Extend base layout -- >{% extends "base.html" %}{% block content %}< table> <tr valign = "top"> <td> </td>
However, you need to make a judgment that the link is displayed only when the user browses his/her personal data page, rather than browsing any personal data page.
The following is the latest personal data page, which contains the newly added fields and the text "about me:
The last point is left for you to study.
It seems that some of the above columns have made the personal data page perfect, right? Think about it carefully. But we still have some bugs to fix.
I wonder if you have found out?
Let me remind you, I have mentioned this bug when we browse user login in the previous chapter. Now we have made the same mistake in the above Code.
Think about it. If you know what the problem is, you can comment on it below. I will detail this bug in the next chapter and explain how to fix it.
As before, I will package and download the Code mentioned today.
Microblog-0.6.zip.