Make social media applications with Flask #3: Register user and Store data in SQLite, Base Layout
Repository
What Will I Learn?
- Register user and Store data in SQLite
- Base Layout and Extends Layout
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
I will still continue the tutorial on social media applications with Flask. In the tutorial before we have learned how to make routing and templating systems. In this tutorial, we will discuss how the authentication system in this application. In the previous tutorial, I created a function so that the user can register. In this tutorial, I will continue our application by creating login pages. we just start this tutorial.
Register User
In the previous tutorial, I created a function from the user register, but I have not added a function to save the database to SQLite. SQLite is the database driver that we use in this tutorial. We can see the register function below:
@app.route('/register', methods =['GET', 'POST'])
def registerPage():
if request.method == 'POST' and request.form['username']:
try:
with database.atomic():
user = User.create(
username = request.form['username'],
password = md5(request.form['password'].encode('utf-8')).hexdigest(),
email = request.form['email']
)
return redirect(url_for('showHomePage'))
except IntegrityError:
return 'There is something error'
return render_template('register.html')
- Model User: We have created the User model as an abstraction from the table in our database. The following is the model form from the User table.
User model
class User(BaseModel):
username = CharField(unique=True)
password = CharField()
email = CharField(unique=True)
join_at = DateTimeField(default=datetime.datetime.now())
There are 3 user columns which must be required, join_at is not required to be filled because we give a default value default=datetime.datetime.now()
.I give unique value = True. So that the values of the columns are always different. For more details, I will demonstrate when the user registers.
Note: We can see at the end of the picture there is an error because we haven't imported some of the functions that we use. I haven't imported a redirect()
.
from flask import Flask, render_template, request, url_for, redirect
The data we have entered when we register can be seen in the SQL console item, to enter the database we can use SQLite tweets.db. tweets.db
is the database that we created in the previous tutorial. We can see the data through the SQLite console like the example below:
We can see in the picture above our data has been successfully inserted into the user table, We can enter the table from the database like the usual SQL language, we can enter the user table with select * from User
.
Base Layout
I will make a layout that will make our pages more structured. This page will be the base page of the page we will use. So later we can import asset CSS and javascript through just one page. F more details, we can see in layout.html below:
Layout.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name='viewport' content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
<title>Social media application</title>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Dropdown
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Something else here</a>
</div>
</li>
<li class="nav-item">
<a class="nav-link disabled" href="#">Disabled</a>
</li>
</ul>
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
</div>
</nav>
{% block body %}
// Your template
{% endblock %}
</body>
</html>
In this block body,
{% block body %} {% endblock %}
our template will be rendered, the dynamic part of the template that we render on each different route.In the base layout, I use the Navbar from the bootstrap.
By using the base layout asset in the application, we can render it in my main layout as an example of the following CCS of bootstrap.
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
- Use Base Layout
We have created a base layout in the layout.html file, now that we can use the base layout we applied, the base layout is a static part of our website display. the dynamic part will always change as needed. I will change the template from the homepage that has the index.html template.
Index.html
{%extends "layout.html" %}
{% block body %}
<div class="jumbotron">
<h1 class="display-4">Welcome to homepage, I'm using base layout</h1>
<p class="lead">Welcome to the social media application that uses flasks</p>
<hr class="my-4">
<p>For new users you are required to register to use this application. please click register</p>
<a class="btn btn-primary btn-lg" href="{{url_for('registerPage')}}" role="button">Register</a>
</div>
{% endblock %}
To extend the base layout we can use syntax like this
{%extends "layout.html" %}
. When we add it means we don't need HTML tags like this<html> </ html>
and we don't need to import CSS anymore, because the CSS has been imported in the base layout.We can use the opening and closing tag, to limit the template section, we can do with this
{% block body %} {% endblock %}
and if we run the application then we can see results like this.
We can see in the picture above we can render the navbar in our diseño base section and now I don't need to import CSS in each template that I used.
- Register Layout
Now we will create and use the base layout on the register page but I will change the navbar in our base layout to match the routing we have.
Layout.html
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="{{url_for('showHomePage')}}">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{url_for('registerPage')}}">Register</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Login</a>
</li>
</ul>
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
</div>
Home page:
<a class="nav-link" href="{{url_for('showHomePage')}}">Home <span class="sr-only">(current)</span></a>
. showHomePage is the name of the function we use in routing'/'
.Register page:
<a class="nav-link" href="{{url_for('registerPage')}}">Register</a>
. registerPage is the name of the function we use in routing'/register'
.
On the register page I will enter the base layout that we use as follows:
register.html
{%extends "layout.html" %}
{% block body %}
<div class="jumbotron">
<h1 class="display-4">Register Page</h1>
<form action="{{url_for('registerPage')}}" method="POST" autocomplete="off">
<div class="form-group">
<label for="username">Username</label>
<input type="text" class="form-control" id="username" name="username" aria-describedby="emailHelp" placeholder="Enter username">
</div>
<div class="form-group">
<label for="email">Email address</label>
<input type="email" autocomplete="off" class="form-control" id="email" name="email" aria-describedby="emailHelp" placeholder="Enter email">
<small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small>
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" class="form-control" id="password" name="password" placeholder="Password">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
{% endblock %}
The explanation is not much different from the one on the homepage. I will run the application and see the results as shown below.
We can see as the picture above we succeeded in making navigation based on routes that we have, enough until here my tutorial this time may be useful for you. thank you for following this tutorial.
Curriculum
- Web development with flask
Web developement with python #1 : Flask initialization and Routing system
Web development with python #2 : Templating jinja2 and Method POST on routing system
Web development with python #3 : Get method, Query parameter and Navigate Routing
Web development with python #4: Store cookie and Get cookie in template
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
File in python #2 : The interaction between user input, Read CSV file
File in python #3 : Write CSV file, Read and Write JSON file
- Class-based views
Tutorial Django - Class based view #2 : Use Class based view method and Get and Post method
Tutorial Django- Class based view #3 : Authentication in Django and Urls Protection globally and specifically
Create Aplication social media with flask
Make social media applications with Flask #2: System routing and Templating, Make user register
Thank you for your contribution @duski.harahap.
After analyzing your tutorial we suggest the following points below:
In sections of your code it's important to have comments, so readers will understand your code better.
It was interesting to have gifs instead of images. Good job!
In the section of your curriculum in my opinion it would be better to have only the link of the first tutorial and the last link of tutorial the same series. The curriculum section is too large.
We look forward to more of your 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!
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!