Repository
What Will I Learn?
- Handle error UserDoesNotExist
- Make the system follow a user
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 everyone, in this tutorial I will still continue with the tutorial series about social media applications using flasks. we have learned a lot about the concepts and basics of making social media-based applications. You can see the previous tutorial in the curriculum section, I suggest you follow the tutorial beforehand so you don't get confused. In this tutorial, I will discuss a fairly important concept of social media for following and unfollowing other users. maybe we don't understand how the concept and its implementation are, we just start this tutorial.
Handle error in profile route
Before we enter the interesting part, I will make a little refactor of the code or additions to the handling error section, if we look at the previous tutorial we have not handled if an error occurs in the username that is invalid or does not exist. for that we can overcome it by using try and catch.
If we don't handle the error then we can see an error in the console like the following:
We try to find jhondoe that in fact do not exist. then we will receive an error as we saw above. we can solve the error better by using try catch as below:
app.py
@app.route('/user/<username>')
def userProfile(username):
try: // use the try and catch
user = User.get(User.username == username)
except User.DoesNotExist:
abort(404) // set abort 404 to render page not found
messages = user.messages.order_by(Message.published_at.desc())
return render_template('profile.html', messages = messages, user=user)
We can use a
try
when you have not retrieved data from the user and test whether the user data existsUser.DoesNotExist:
We can use the
abort()
function for that we must improt abort like this:from flask import abort
and if there is no error then we can see the picture below:
We can see we succeed to handle the error that occurred. Now we will go into the follow and unfollow feature.
Follow user
I will make one of the important features of our application, namely features to follow another user. In order to make such features, we already have a table called Relationship and I have also made abstractions from the table into the Relationship model.
app.py
class Relationship(BaseModel):
from_user = ForeignKeyField(User, backref='relationships')
to_user = ForeignKeyField(User, backref='related_to')
In this model only have two fields, namely from_user and to_user and both of them have their respective backrefs, the relationships and related_to
from_user is a field that will be filled in by users who are currently logged in which are automatically users who will follow others.
to_user is the person that will be followed by the user who is logged in.
Backend
I will start from the backend first so that the frontend will adjust it. I will create a new routing that has a username parameter. the username that we will later use as a reference to get user data. The following is the routing that we will use.
app.py
@app.route('/user_follow/<username>', methods =['POST'])
I will create a new routing, namely /user_follow/<username>
and define methods POST. Then I will create a function to implement the following system in our application.
app.py
@app.route('/user_follow/<username>', methods =['POST'])
def userFollow(username):
try:
user = User.get(User.username == username)
except User.DoesNotExist:
abort(404)
# Atomic transaction
try:
with database.atomic():
Relationship.create(
from_user = get_current_user(),
to_user = user
)
except IntegrityError:
pass
flash("you have followed "+ username)
return redirect(url_for('userProfile', username=username))
I define the
userFollow()
function and what I will first do in this function is to get the user data from the parameters in routingUser.get(User.username == username)
.I will use the database atomic transaction
with database.atomic():
to avoid mistakes when following the user, because this function is quite risky. So I will fail the transaction to the database when an error occurs.I have created a Relationship model class, so I can enter data into the database with the
create()
function. I will enter two data in the Relationship table field.from_user: We can take the value from_user from
from_user = get_current_user()
, get_current_user is a function that we have created in the previous tutorial, the following functions:
def get_current_user():
if session.get('logged_in'):
return User.get(User.id == session['user_id'])
We will retrieve user data by session.
to_user: And the value to_user from
to_user = user
. user variable we get fromuser = User.get(User.username == username)
.I will catch an error in
except Integrity Error:
at this time I will only pass the error with apass
.And at the end of the code, I will give a flash message to the user, to notify that it has successfully followed that user.
Frontend
I have finished the backend, now I will switch to the frontend. In the frontend section, I will create an interface so users can follow other users. I will add a button in the profile.html section.
profile.html
{%extends "layout.html" %}
{% block body %}
<div class="jumbotron">
{% if user.username != session.username %}
<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 %}
<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 %}
- I will add some new code, all I have to do is make a button that will appear only when the user is not the same as the user who is logged in because we are not likely to follow ourselves. We can check by comparing user and session data, like the following example:
{% if user.username != session.username %}
{% endif %}
we compare the username that is in the user data and the one in the session. We can see the demonstration in the picture below:
We can see in the picture above, the user who is logged in is milleaduski1994, So when we access user / milleaduski1994
we will not see the follow button on the profile, but if we wait for routing user/User2
we can see the button because the user who is logged in is different from the user data that is accessed.
- And I will create a form that submit to
<form method = "post" action = "{{url_for ('userFollow', username = user.username)}}">
, In my action I will add the username parameter according to what we have created in the previous backend sectionurl_for ('userFollow', username = user.username)
. For more details, we can see the picture below:
As we can see in the picture above we managed to follow User2, to make sure we can see the table in tweets.db.
If we look at the picture above we only get data like this 1 | 2
, as we know in the table relationship only has 2 columns, namely from_user and to_user. So the point is that user id 1 (from_user) follows user id 2(to_user).
This means we have succeeded in creating a follow system on our application, I hope you can develop this application for the better, thanks for following this tutorial. hopefully, it will be useful for you.
- Web development with flask
Web developement with python #1 : Flask initialization and Routing system
Web development with python #6 : Use flash message and combine it with framework boostrap
- File in python
File in python #1 : Read file and Write file and Modes file
- Class-based views
Create Aplication 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
After analyzing your tutorial we suggest the following points below:Thank you for your contribution @duski.harahap.
Thank you for following our suggestion not to repeat content in your tutorial. This contribution was much better.
The section of your tutorial links gets very large in the tutorial. Put only the links of the tutorials related to this subject.
Your work on GIFs looks really good.
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 @portugalcoin :)
Thank you for your review, @portugalcoin! Keep up the good work!
Congratulations @duski.harahap! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :
Click here to view your Board
If you no longer want to receive notifications, reply to this comment with the word
STOP
To support your work, I also upvoted your post!
Hi @duski.harahap!
Feel free to join our @steem-ua Discord serverYour post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation! Your post is eligible for our upvote, thanks to our collaboration with @utopian-io!
Hey, @duski.harahap!
Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!
Get higher incentives and support Utopian.io!
SteemPlus or Steeditor). Simply set @utopian.pay as a 5% (or higher) payout beneficiary on your contribution post (via
Want to chat? Join us on Discord https://discord.gg/h52nFrV.
Vote for Utopian Witness!