Make social media applications with Flask #9: Context processor and Unfollow system and Implement in the user interface
Repository
What Will I Learn?
- Context processor
- Unfollow system and Implement in the user interface
Requirements
- Basic Python
- Install Python 3
- Install Flask
Resources
- Python - https://www.python.org/
- Flask - http://flask.pocoo.org/
- Peewee http://docs.peewee-orm.com/en/latest/
- Sqlitebrowser https://sqlitebrowser.org/
Difficulty
Basic
Tutorial Content
Hi, everything is still in my tutorial about applications with social media concepts using a flask. I have made this tutorial from the basics if you just followed this tutorial. You can see the previous tutorial in the curriculum section. In the previous tutorial, we made the basic structure of this application and created an authentication system, made a post, and the last one I made was the following user system, this time we will continue the system.
Unfollow user
in system follow a user we have made a follow user feature but it is incomplete if we do not create unfollow features on our system. In this unfollow feature, we need additional verification to check whether the user that we are viewing his profile has been followed or not. to check it, we can start creating a new function to check the user that we are opening his profile. The function that will check whether the user has been followed is is_following()
the function there is a class User.
- Check whether the user has been followed
app.py
def is_following(self, user):
return (Relationship.select()
.where((Relationship.from_user == self) &
(Relationship.to_user == user))
.exists())
This function has two parameters, the first parameter is the default parameter (self) and the second parameter is the user we are about to unfollow. If we look at the Relationship table we can see that user id (1) follows user id (2).
We use self to refer to the user who is logged in.to check I will use
where ()
, I use this function to check the column from_user must be the same value as the user being logged inRelationship.from_user == self
and the to_user column must be the same value as the user that is passed to the parameterRelationship.to_user == user
. I use a logical and (&) operator so when one condition is not fulfilled, the result of this function is false because I use theexists()
method.
Context Processor
We have made the is_following function in the backend section, now our next task is to use the function in the frontend section. so far that we have never done that, to do that we can use context_processor. by using a context processor we will inject data to use it in the frontend, for more details we can see the example below:
app.py
@app.context_processor
def _inject_user():
return {'active_user': get_current_user()}
to make a function on the processor context, I will use this method like this
@app.context_processor
. to define its function the same as another functiondef _inject_user():
.to inject data into the frontend, we can return the data in the form of an object
return {'active_user': get_current_user()}
. The key is'active_user'
, The key here can be used as an alias to be used in the frontend and the value is the result of theget_current_user()
function. This function is a function that we have made in the previous tutorial.
def get_current_user():
if session.get('logged_in'):
return User.get(User.id == session['user_id'])
this function that we often use to get user data that is logged in by session.
- Unfollow system on the frontend
After we finished the backend, we will implement an unfollow system on the frontend. in the profile section I will add additional checks using the function we created, which is is_following()
. For more details, we can see the profile page below:
profile.html
{%extends "layout.html" %}
{% block body %}
<div class="jumbotron">
{% if user.username != session.username %}
{% if active_user.is_following(user)%}
<form method="post" action="{{url_for('userUnfollow', username = user.username)}}">
<p class="bold">{{user.username}} <button class="btn btn-danger">-Unfollow</button></p>
</form>
{% else %}
<form method="post" action="{{url_for('userFollow', username = user.username)}}">
<p class="bold">{{user.username}} <button class="btn btn-primary">+Follow</button></p>
</form>
{% endif %}
{% endif %}
<h1 class="display-4">Welcome to homepage {{user.username}}, I'm using base layout</h1>
<p class="lead">Welcome to the social media application that uses flasks</p>
<hr class="my-4">
<h2 style="text-align: center;">Your feed</h2>
{% for message in messages%}
<h4>{{message.content}}</h4>
<span style="font-size: 10px; font-style: italic;">{{message.published_at}}</span>
{% endfor %}
</div>
{% endblock %}
Because the results of the
is_following()
function are true or false we can use the{% if %}
function. I have created an alias in the context_processor method, with the alias'active_user'
. So to use it we can call the function in context_processor that we inject and then the name of the function we will call as followsactive_user.is_following(user)
. active_user is the aliasNeed to understand that
active_user
is the alias name of the function injected into the frontend andis_following()
is a function in the class User model.I have created a if else function so when the result of
active_user.is_following (user)
is true I have created an if else function so when the result of active_user.is_following (user) is true then we will create a new button that will have a different function.
<form method="post" action="{{url_for('userUnfollow', username = user.username)}}">
<p class="bold">{{user.username}} <button class="btn btn-danger">-Unfollow</button></p>
</form>
- In the
is_following
function I will pass on the user dataactive_user.is_following(user)
that is currently logged in to check whether we have followed the user, at this time we have followed user id 1 following user id 2, we can prove this in the image below:
We can see in the picture above user id 1 (milleaduski1994) has followed user id 2 (User2), So if it doesn't happen we can see how it looks like the image below:
- Create unfollow function
Now I will make the final part of creating an unfollow function that will delete the related data in the relationship table. As we saw in the frontend section above we have created a new form with actions to the userUnfollow function action="{{url_for('userUnfollow', username = user.username)}}"
. Now I will make the function below:
app.py
@app.route('/user_unfollow/<username>', methods =['POST'])
def userUnfollow(username):
try:
user = User.get(User.username == username)
except User.DoesNotExist:
abort(404)
(Relationship.delete()
.where(
(Relationship.from_user == get_current_user()) &
(Relationship.to_user == user))
.execute())
flash("you have unfollowed "+ username)
return redirect(url_for('userProfile', username=username))
This function is not much different from the following user function, we will also pass the username to our routing and use the post method
@app.route('/user_unfollow/<username>', methods =['POST'])
. The only difference is the name of the route.First, we will also check whether the username is Exist or not with method
User.DoesNotExist:
.Then we just use the
delete()
query on the sqlite3 function. When deleting data we need to use where to delete specific data. The first we will match whether relationship.from_user is the same as the user who is logged in(Relationship.from_user == get_current_user())
and the second we will match whether relationship.to_user is the same as the user whose data is retrieved from the username that is passed from routing.user = User.get (User.username == username)
. both values must be true values because we use logical AND (&).After that if successful I will give a notification in the form of a flash message
flash("you have unfollowed "+ username)
and redirect to the userProfile pagereturn redirect(url_for('userProfile', username=username))
.
We can see the picture above we managed to make the system follow and unfollow the user for more details we can see in the table relationship, make sure the data relationship has been deleted.
We can see above that there is no longer a relationship record for a table relationship, this means that the system we are running is running well, you can develop this system again, just a few of my tutorials this time, hopefully, it can be helpful and useful for you. thank you for following this tutorial.
Create Application social media with flask
Make social media applications with Flask #2: System routing and Templating, Make user register
Make social media applications with Flask #3: Register user and Store data in SQLite, Base Layout
Make social media applications with Flask #4: Login system and Use session to manage user data
Make social media applications with Flask #6: View decorator and Post the first status
Make social media applications with Flask #7: The use of backref and Create profile features
Make social media applications with Flask #8: Handle error and Make the system follow a user
Thank you for your contribution @duski.harahap.
After analyzing your tutorial we suggest the following points below:
Be careful with the writing of your code, it is very important to have the code ident so readers do not have difficulty reading.
In your tutorial try to put more features.
Your work with GIFs looks great, thanks for your work.
Looking forward to your upcoming tutorials.
Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.
To view those questions and the relevant answers related to your post, click here.
Need help? Chat with us on Discord.
[utopian-moderator]
Thank you for your review, @portugalcoin! Keep up the good work!
Hey, @duski.harahap!
Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!
Get higher incentives and support Utopian.io!
Simply set @utopian.pay as a 5% (or higher) payout beneficiary on your contribution post (via SteemPlus or Steeditor).
Want to chat? Join us on Discord https://discord.gg/h52nFrV.
Vote for Utopian Witness!