Flask Web Development User Profile _3

Source: Internet
Author: User

Continue to the previous chapter, the previous section is about the user to edit the content of their own pages, the content is relatively simple, the real name, from where, self-introduction of the information, and e-mail and user name, you have no place to change, because in the register when the registration.

But as a site manager, you must have permission to modify the user's information, or even for them to modify the email address, or the user name, and permissions

Do not look at just one more to modify the user information of other users of the form, this chapter has a few knowledge points need special attention


Go to the point, since you can modify the content more, then we definitely want to create a new form, as the admin can see and modify the form

Class Editprofileadminform (Form): email = stringfield (' email ', validators=[required (), Length (1,64), email ()]) Username = Stringfield (' username ', validators=[required (), Length (1,64), Regexp (' ^[a-za-z][a-za-z0-9_.] *$ ', 0, ' numbers,dots or underscores ')] confirmed = Booleanfield (' confirmed ') role = Selectfield (' role ', coerce = int) #注 Meaning, the field here is select, which is the dropdown select list Name = Stringfield (' Real Name ', Validators=[length (0,64)]) location = Stringfield (' Location ', Validators=[length (0,64)]) About_me = Textareafield ("About Me") Submit = Submitfield (' Submit ') def __init__ ( Self,user,*args,**kwargs): #这里一定要注意到, when the form is generated, it is necessary to take the parameter user!!! Super (Editprofileadminform,self). __init__ (*args,**kwargs) self.role.choices = [(role.id,role.name) for role in                                                                                                                   Role.query.order_by (Role.name). All ()]self.user = user #上面的role. Choices property, is the option for form role, which is written separately for Def Validate_email (Self,field): If Fiel D.data! = Self.user.email andUser.query.filter_by (email = field.data). First (): #检验email是否发生更改且是否重复raise validationerror (' email already registered .') def validate_username (Self,field): #检验username是否发生更改且是否重复if field.data! = self.us Er.username and User.query.filter_by (username = field.data). First (): Raise ValidationError (' username already in use ')


First, write simple:

1: About Validate_email and Validate_username, in the previous chapters we have already mentioned, in the form of the settings, if the function is set to start with the Validate_, then he will be in the validation, and the above form of ordinary validation together with. So how did he one by one correspond? In fact, is validate_email , underline the content behind , corresponding to the name of the form above, and then specific, corresponding to the form.email, that is, the form instance object email properties.

So field.data this meaning is actually form.email.data! = Self.user.username.

What do you mean by that sentence? is when you as a manager in the modification of user information, if the data has changed, and this changed email in the database search has been used by people

You will get an error: Email already registered.

The same applies when modifying user username

Because, for all users, username and email should be unique.


----------------------------------------------------------------------here to interrupt Flask source code -------------------- --------------------------------------------------------------

app\main\forms.py Interior

From FLASK.EXT.WTF import Form

flask.wtf\__init__.py Import form via form.py

From. Form Import Form

and the form definition within the form.py

Class Form (Secureform):

The secureform is imported through the following line

From Wtforms.ext.csrf.form import Secureform

Then you can see it in wtforms\ext\csrf\form.py.

Class Secureform (Form)

Well, we see that the form is eventually imported from the Wtforms form.

From Wtforms.form Import Form


So, in the end, we found this validate_ definition in the form class.



---------------------------------------------------------------------------- Source to find the end -------------------- -----------------------------------------------------------



2: We come to the content about Selectfield and choices

Class Editprofileadminform (Form): #.. role = Selectfield (' role ', coerce = int) #: def __init__ (Self,user,*args,**kwargs): Super (Editprofileadminform,self) __init__ (*args,**kwargs) Self.role.choices = [(role.id,role.name) for role in Role.query.order_by (Role.name). All ()]


From the official documentation we can see that you have 2 options, one is a solid-state setting option , such as the choices in the document below, written inside Selectfield

The second is the dynamic option , which is defined within the additional function, through the language, dynamically and as a Selectfield link to the class properties

Back to the example in the book, he was obviously using the dynamic settings in the __INIT__ initialization function, with the choices set

For role in Role.query.order_by (Role.name). All () This sentence is arranged by the name inside the role and all iterations

As we have already learned in the previous chapters, we currently have 3 Role,name attributes with the name attribute of 'User', 'moderator', 'administer'

Therefore, the corresponding (Role.id,role.name) has 3 options

# Leave a position to write the meaning of value and label

Here, after the completion of a back, you will be able to fully understand the value and label corresponding to the meaning of

We can see that corresponding to our example, the label shown is Role.name, that is, the second parameter in the meta-ancestor label

and his corresponding internal logic (that is, the book's identifier), is actually role.id, we can see in the second picture below the form of the database

So, when you choose a different role name, you give it a different ID.

The extra point here is that when the models is established, there is a relationship in the role class, and his backref is "role", and I understand that this is the corresponding user class when creating an instance, User is able to access the role class through the Role property , and the class object of the role class as a property of the user itself , and, to put it bluntly, package all the properties of the role class into an instance, Assign the role property to user.

So, in the example in the book, you choose different role, it is equal to choose a different user permission level.











After the form part is finished, we have to write the view part function .


@main. Route ('/edit-profile/<int:id> ', methods = [' GET ', ' POST ']) @login_required @admin_requireddef edit_ Profile_admin (ID): #注意: The function here with the parameter id of User = User.query.get_or_404 (id) Form = editprofileadminform (user = user) if Form.validate_on_submit (): User.email = Form.email.datauser.username = form.username.datauser.confirmed = Form.confirmed.datauser.role = Role.query.get (form.role.data) User.Name = Form.name.datauser.location = Form.location.datauser.about_me = Form.about_me.datadb.session.add (user) Db.session.commit () Flash (' The profile has been updated. ') Return Redirect (Url_for ('. User ', username = user.username)) Form.email.data = User.emailform.username.data = User.usernameform.confirmed.data = User.confirmedform.role.data = user.role_id #注意: When the initial value is set, the role_id is used, and the Role_ ID is a foreign key, corresponding to Roles.id, is the roles table Idform.name.data = User.nameform.location.data = User.locationform.about_me.data = User.about_mereturn render_template (' edit_profile.html ', form = Form,user = user)

Above here, form.role.data the default value of this link, using the role_id to set up, role_id corresponding to the user, the corresponding ID in the roles table, that is, the permission level.

Class User (usermixin,db. Model): #...<span style= "white-space:pre" ></span>role_id = db. Column (db. Integer, Db. ForeignKey (' roles.id '))    #这里的role_id, is equal to the ID of the roles table


We also need to explore the Selectfield used to select User roles. When the initial value of this field is set, role_id is assigned to Field.role.data, because the tuple list set in the Choices property is
use a numeric identifier to represent each option. After the form is submitted, the ID is extracted from the data property of the field, and the role object is loaded with the extracted ID value at the time of the query. Use the Coerce=int parameter when declaring Selectfield in the form.
The function is to ensure that the data property value of this field is an integer.


The important point here is that the red hint part, the choices property, although the option he displays is the name of the string, such as "User" "administer", but his actual logical data is controlled by ID.


One of the important points to note is: don't confuse form.role.data with User.role !!

Form.role.data He corresponds to is actually a number

And user.role he corresponds to a class object! So when submitting the form, he was extracted by User.role = Role.query.get (form.role.data).


When the logic is over, it's the rendered page.

As an administrator, there must be one more button on the page you want to see, and you can edit it in admin mode.

So, the code is as follows, there is a judgment statement, when you are an administrator, the button will be displayed

{% if Current_user.is_administrator ()%}<a class= "btn Btn-danger" href= "{{url_for ('. Edit_profile_admin ', id= user.id)}} ">            Edit profile [admin]</a>


As follows







On the question of how this views function is to value the ID, tangled up the whole day

Because I do not know how the value of this ID is taken, I would have gone to templates/user inside to find it, Found inside the user.id is generated by the user, but the user is imported through the views function, however, the user is also through the ID in the database to take the value, this is not a dead loop?


Here in fact, I went into a misunderstanding, but also I did not look at the previous article carefully

The current page is actually built on top of the Xxxxxx/user/allenxu , not xxxxxx/edit-profile

What do you mean? For example, as an administrator, you have entered the user page of Bob, the URL must be Xxxxxx/user/bob

Who is the user at this time? At this time the user of the current page, this variable is actually bob

So, as the administrator, press a red edit button, is built on the user this page!!! So the current user can get the value.

Not what I thought was built in the edit page!!






The following is the user's views function definition, we can see the user of the incoming template, in fact, through username to filter out, and username is this page belongs to which user's meaning

So, in user/<username> All operations on this page, user this variable belongs to <username> this user, not your administrator !!!


Current_User is the administrator

User is the person that the page represents





Flask Web Development User Profile _3

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.