Make social media applications with Flask #8: Handle error and Make the system follow a user

in #utopian-io5 years ago

Repository

https://github.com/python

What Will I Learn?

  • Handle error UserDoesNotExist
  • Make the system follow a user

Requirements

  • Basic Python
  • Install Python 3
  • Install Flask

Resources

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:

Screenshot_4.png

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 exists User.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:

ezgif.com-video-to-gif (5).gif

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 routing User.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 from user = User.get(User.username == username).

  • I will catch an error in except Integrity Error: at this time I will only pass the error with a pass.

  • 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:

ezgif.com-video-to-gif.gif

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 section url_for ('userFollow', username = user.username). For more details, we can see the picture below:

ezgif.com-video-to-gif (1).gif

As we can see in the picture above we managed to follow User2, to make sure we can see the table in tweets.db.

Screenshot_6.png

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

Tutorial Django - Class based views #1 : Installation and configuration Django, Using a template system



Create Aplication social media with flask

Make social media applications with Flask #1: Design database and initial structure, Following and follower functions

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 #5: Authentication during registration and User notification

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

Proof of work done

https://github.com/milleaduski/python-web-app

Sort:  

Thank you for your contribution @duski.harahap.
After analyzing your tutorial we suggest the following points below:

  • 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 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) :

You published more than 70 posts. Your next target is to reach 80 posts.

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!

Support SteemitBoard's project! Vote for its witness and get one more award!

Hi @duski.harahap!

Your 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!
Feel free to join our @steem-ua Discord server

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!

Coin Marketplace

STEEM 0.26
TRX 0.11
JST 0.032
BTC 63617.36
ETH 3070.79
USDT 1.00
SBD 3.82