Learn this chapter, feel a bit back to the 8th chapter of the Taste ... There are several pits or later need to be quiet to fill the heart
For the relationship between the models, prepare to separate out a test article, leave a location for the link
#
# Leave a position for the foreign chapter
#
is a self-referencing diagram that is used in situations where there is only one entity (user) on both sides of the association table, like attention and attention.
The association table for this example is follows, where each row indicates that one user is following another user . A one-to-many relationship on the left side of the graph links the user to a set of records in the follows table, and the user is a concern. The right side of the figure shows
A one-to-many relationship that links users to a set of records in a follows table, and the user is the person who is being followed.
What's the meaning of the above remark?
It is in the follows table, his form is 2 columns, follower_id and followed_id, the ID of the inside is actively concerned about the person's ID and the ID of the followers
Class follow (db. Model): __tablename__ = ' follows ' follower_id = db. Column (db. Integer, Db. ForeignKey (' users.id '), primary_key=true) followed_id = db. Column (db. Integer, Db. ForeignKey (' users.id '), primary_key=true) timestamp = db. Column (db. DateTime, Default=datetime.utcnow)
From the Follow Class property definition inside we can see, follower_id as a foreign key, corresponding to Users.id, and followed_id as a foreign key, corresponding to User.ID
Then look at the corresponding users table, which is the user class.
Special attention is paid to the value of the Foreign_keys,
Followed said that the people who have been concerned , he corresponds to the follow class inside the follower_id this attribute, that is, who is concerned about, the specific value is the ID number
Followers said his fans , corresponding to the follow class inside the followed_id, this is a bit of a mouthful, this is actually their own fan ID
On the lazy, has been reproduced in other predecessors of an article, and about Cascade, is and delete objects, the contents of the association table will not be deleted together, follow up
Class User (usermixin,db. Model): #...followed = Db.relationship (' Follow ', Foreign_keys=[follow.follower_id],backref=db.backref (' follower ', Lazy= ' joined '), lazy= ' dynamic ', cascade= ' all, Delete-orphan ') followers = db.relationship (' Follow ', foreign_keys=[ Follow.followed_id],backref=db.backref (' followed ', lazy= ' joined '), lazy= ' dynamic ', cascade= ' all, Delete-orphan ')
Then add a method to the user instance
Attention, you must at least do a button to the user, that this button design to 2 functions, attention and cancellation of attention, 2 States, whether it has been concerned, whether it has been concerned
Class User (usermixin,db. Model): #...def Follow (self, user): If not self.is_following (user): F = Follow (follower=self, Followed=user) Db.session.add (f) def unfollow (self, user): F = self.followed.filter_by (Followed_id=user.id). First () if f: Db.session.delete (f) def is_following (self, user): Return self.followed.filter_by (Followed_id=user.id). First () was not Nonedef is_followed_by (self, user): Return self.followers.filter_by (Follower_id=user.id). First () was not None
The follow () method manually inserts the follow instance into the associated table, which joins the followers and the followers, and gives the program the opportunity to set the value of the custom field. Two users joined together are manually passed into the constructor of the follow class, create a new follow instance, and add the instance object to the database session as usual. Note that there is no need to manually set the timestamp field here because the default value, the current date and time, is specified when the field is defined. The Unfollow () method uses the followed relationship to find the follow instance of the connected user and the user being followed. To destroy a join between these two users, simply delete the follow object. The Is_following () method and the Is_followed_by () method search for a specified user in a one-to-many relationship on both left and right, and return true if found.
The above text is in the book, you can see that the follow () method finally through the Db.session.add to insert the new object F, and the Unfollow () method is db.session.delete to delete this instance
Under step, in the follow method, he through self.is_following (user) to check whether the current user is already concerned about the state, the following is_following method you can see, return is not None
That is, the follow method continues to insert a new follow instance, and finally inserts the database, in the case where the result of the check is not None
The Unfollow method is to find out how many people are concerned through the followed property of the Self object, and then through Followed_id=user.id, find out the current user object and give it to f
If f exists, the F object is deleted through the session
Is_following method, through the self object of the followers inside, with user.id to check whether you have been concerned about this person, return results not None, non-empty
Is_followed_by, like, look at the self object of his own fan group, through User.ID find whether there is this person, return result is not None, non-empty
The above 2 methods represent a state, not a functional method.
{% if Current_user.can (permission.follow) and user! = Current_User%} {% if not current_user.is_following (user)%}<a href= "{{url_for ('. Follow ', Username=user.username)}}" class = "btn Btn-primary ">follow</a>{% Else%}<a href=" {{url_for ('. Unfollow ', Username=user.username)}} ' class = ' btn Btn-default ">unfollow</a>{% endif%}{% endif%}<a href=" {{url_for ('. Followers ', Username=user.username)} } ">followers: <span class=" badge ">{{user.followers.count ()}}</span></a><a href=" {{url_for ('. followed_by ', Username=user.username)}} " >following: <span class= "badge" >{{user.followed.count ()}}</span></a>{% if Current_user.is_ Authenticated and user! = Current_User and user.is_following (current_user)%}| <span class= "Label Label-default" >follows you</span>{% endif%}
After the front-end rendering is written, it is necessary to write the routing control
@main. Route ('/follow/<username> ') @login_required @permission_required (Permission.follow) def follow ( Username): User = User.query.filter_by (username=username). First () if User is None:flash (' Invalid user. ') Return Redirect (Url_for ('. index ')) if current_user.is_following (user): Flash (' You is already following this user. ') Return Redirect (Url_for ('. User ', username=username)) current_user.follow (user) Flash (' You're now following%s. ') username) return Redirect (Url_for ('. User ', username=username)) @main. Route ('/unfollow/<username> ') @login_ Required@permission_required (Permission.follow) def unfollow (username): User = User.query.filter_by (username= username). First () if User is None:flash (' Invalid user. ') Return Redirect (Url_for ('. index ')) if not current_user.is_following (user): Flash (' is not following this user. ') Return Redirect (Url_for ('. User ', username=username)) current_user.unfollow (user) Flash (' You're now unfollow%s '% username) return Redirect (Url_for ('. User ', username=username))
Follow and Unfollow as a group
Follow logic is: There are 2 prerequisites, need to be logged in state, need to have follow permissions, through the URL of the username, filter out the object user, and then to judge
Prompt for Flash message if user does not exist, invalid user
If the user has already followed the user, prompt the flash message that the user is already concerned
If you are not concerned, execute the current user's follow method and follow the user
Unfollow the same logic.
@main. Route ('/followers/<username> ') def followers (username): User = User.query.filter_by (username=username). First () If User is None:flash (' Invalid user. ') Return Redirect (Url_for ('. index ')) page = request.args.get (' page ', 1,type=int) pagination = User.followers.paginate ( page,per_page=current_app.config[' Flasky_followers_per_page '],error_out=false) follows = [{' User ': Item.follower, ' Timestamp ': Item.timestamp}for item in Pagination.items]return render_template (' followers.html ', user=user,title= " Followers of ", endpoint= '. Followers ', pagination=pagination,follows=follows) @main. Route ('/followed-by/< Username> ') def followed_by (username): User = User.query.filter_by (username=username). First () if User is None:flash ( ' Invalid user. ') Return Redirect (Url_for ('. index ')) page = request.args.get (' page ', 1,type=int) pagination = User.followed.paginate ( page,per_page=current_app.config[' Flasky_followers_per_page '],error_out=false) follows = [{' User ': Item.follower, ' Timestamp ': Item.timestamp}for item in PaginatIon.items]return render_template (' followers.html ', user=user,title= "followed by", endpoint= '. Followed_by ', Pagination=pagination,follows=follows)
The next 2 are the user's fan page and the people who are interested in the page
The logic is similar to the above, and is filtered out by username to the user
Prompt for Flash messages if the user does not
Otherwise, you will be paged to show your fan team and idol team
Let's take a look at the whole
Point of concern after the change
Fan Page
Flask Web Development followers