If you know Python, you can make a web application with Django

This article is the last day of Django Advent Calendar 2020.

Introduction

Nice to meet you.

I usually use Django to develop web apps.

-Siltrend

This time has come this year as well. By the way, I posted on the same day last year.

-Django's Personal Tips

This year's Django Advent Calendar 2020 is also great and has lots of practical articles. I enjoyed seeing you.

Personally, I think the beauty of Django is that you can make ** "easy" ** applications ** "easily" **. So, in this article, I'd like to describe the process of creating a simple and basic ** Django application, along with ** code.

I hope this article has contributed to the further spread of Django.

table of contents

-Preparation -Create Application -Create Model -Create View -Create Template --Routing Definition -Completed

Preparation

First, let's do ** simple preparations ** before building the application.

Install Django

Install django. Execute the following command from the terminal for Linux OS and Mac, or from the command prompt for Windows.

python


$ pip install django

Collecting django
  Downloading https://files.pythonhosted.org/packages/08/c7/7ce40e5a5cb47ede081b9fa8a3dd93d101c884882ae34927967b0792f5fb/Django-3.1.4-py3-none-any.whl (7.8MB)
     |████████████████████████████████| 7.8MB 2.1MB/s 
Requirement already satisfied: pytz in /Users/rinego/.pyenv/versions/3.8.3/lib/python3.8/site-packages (from django) (2019.3)
Collecting asgiref<4,>=3.2.10 (from django)
  Downloading https://files.pythonhosted.org/packages/89/49/5531992efc62f9c6d08a7199dc31176c8c60f7b2548c6ef245f96f29d0d9/asgiref-3.3.1-py3-none-any.whl
Collecting sqlparse>=0.2.2 (from django)
  Downloading https://files.pythonhosted.org/packages/14/05/6e8eb62ca685b10e34051a80d7ea94b7137369d8c0be5c3b9d9b6e3f5dae/sqlparse-0.4.1-py3-none-any.whl (42kB)
     |████████████████████████████████| 51kB 3.5MB/s 
Installing collected packages: asgiref, sqlparse, django
Successfully installed asgiref-3.3.1 django-3.1.4 sqlparse-0.4.1

Create a django project

Create a django project with the following command.

python


$ django-admin startproject my_project

When you execute the command, the following files will be created.

my_project/
    manage.py
    my_project/
        __init__.py
        asgi.py
        settings.py
        urls.py
        wsgi.py

Move to the my_project directory on the first level and make various settings after that.

python


$ cd my_project

Project settings

Django's settings are defined in my_project/my_project/settings.py.

You don't have to change the database settings unless you are particular about it. It is a standard and nice setting.

Let's leave only ** language and time zone ** in Japan.

my_project/my_project/settings.py


# LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'ja'

# TIME_ZONE = 'UTC'
TIME_ZONE = 'Asia/Tokyo'

Database migration

First, migrate your database to create a database managed by Django.

python


$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying auth.0012_alter_user_first_name_max_length... OK
  Applying sessions.0001_initial... OK

Running the command will create a file called my_project/db.sqlite3.

Creating super user

Let's also create ** super user ** (administrator of the app to be created) at this timing.

python


$ python manage.py createsuperuser
Username (leave blank to use 'hoge'): admin
Email address: [email protected]
Password: XXXXX
Password (again): XXXXX
Superuser created successfully.

You will be asked the following items.

Make sure you don't forget the Username`` Password, as you will use it later. If you enter a simple one for Password, you will be asked" Is it common but good? ".

python


This password is too common.
Bypass password validation and create user anyway? [y/N]: 

It doesn't matter if the email address is appropriate.

Start the development server

Once you've done this, let's start the ** development server ** once. Start the development server with the command python manage.py runserver.

python


$ python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
December 18, 2020 - 08:54:54
Django version 3.1.4, using settings 'my_project.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

In this state, try accessing http://127.0.0.1:8000/ with a browser.

It is OK if the following screen is displayed.

1.png

Quit the developer server with control + c.

If you can do so far, you should have built the necessary environment for the time being, so all you have to do is write the code.

Creating an application

Now let's create an application.

This time, let's create an application that can ** create, edit, browse, and delete simple data **.

It's just like the toy app in ruby on rails tutorial.

In addition, Django has adopted the ** MTV model design concept **. It's not difficult at all, it's a replacement for each MVC model with a common design pattern.

MTV.png

The application is completed by defining Model, Template and View. (The name View is the most confusing ...)

Creating an application

First, let's create an application.

python


python manage.py startapp sample_app

When you execute the command, it should have the following hierarchical structure.

python


my_project/
    manage.py
    my_project/
        __init__.py
        asgi.py
        settings.py
        urls.py
        wsgi.py
    sample_app/
        __init__.py
        admin.py
        apps.py
        migrations
        models.py
        tests.py
        views.py

In Django, under the project directory my_project /, The project setting my_project/my_project / and the application directory my_project/sample_app / are linked.

Registering the application in the project

After creating the application, let's register it in the project. If you do not do this, the application will not be recognized by the project.

If you open my_project/sample_app/apps.py, you will find a class called SampleAppConfig. Add this to INSTALLED_APPS in my_project/my_project/settings.py with the string *'sample_app.apps.SampleAppConfig', *.

my_project/my_project/settings.py


INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'sample_app.apps.SampleAppConfig', # Add
]

Now you have created the application for the time being. From the next, we will actually create various parts of the application.

Creating a Model

First, let's create a ** Model (database definition) **.

Define the data model of the application you want to create in my_project/sample_app/models.py.

my_project/sample_app/models.py


from django.db import models


class Post(models.Model):
    name = models.CharField('user name', max_length=15)
    micropost = models.CharField('tweet', max_length=140, blank=True)

    def __str__(self):
        return self.name

In this way you can define the data structure of the application you want to create. By the way, user name and tweet are arbitrary strings. Give it a name that will help you identify what data you intended to define later.

Model activation

Once you have created a model, you need to activate it.

Create a migrate file to reflect the changes in my_project/sample_app/models.py with the following command.

python


$ python manage.py makemigrations sample_app
Migrations for 'sample_app':
  sample_app/migrations/0001_initial.py
    - Create model Post

Now that the migrate file is created, reflect it in the database with the following command.

python


$ python manage.py migrate sample_app
Operations to perform:
  Apply all migrations: sample_app
Running migrations:
  Applying sample_app.0001_initial... OK

This completes the model creation.

Create View

Next, create a ** View (process definition) **.

In my_project/sample_app/views.py, define each function of" Create "," Modify "," List ", and" Delete "with a function.

my_project/sample_app/views.py


from django.shortcuts import render, get_object_or_404, redirect
from django.forms import ModelForm

from sample_app.models import Post


def create_post(request):
    """
Create new data
    """
    #Create a new object
    post = Post()

    #When loading a page
    if request.method == 'GET':
        #Create form with newly created object
        form = PostForm(instance=post)

        #Pass form to Template when loading page
        return render(request,
                      'sample_app/post_form.html',  #Template to call
                      {'form': form})  #Data to pass to Template

    #When the execute button is pressed
    if request.method == 'POST':
        #Create form with POSTed data
        form = PostForm(request.POST, instance=post)

        #Validation of input data
        if form.is_valid():
            #If there is no problem with the check result, create data
            post = form.save(commit=False)
            post.save()

        return redirect('sample_app:read_post')


def read_post(request):
    """
Display a list of data
    """
    #Get all objects
    posts = Post.objects.all().order_by('id')
    return render(request,
                  'sample_app/post_list.html',  #Template to call
                  {'posts': posts})  #Data to pass to Template


def edit_post(request, post_id):
    """
Edit the target data
    """
    #Get the target object with ID as an argument
    post = get_object_or_404(Post, pk=post_id)

    #When loading a page
    if request.method == 'GET':
        #Create form by target object
        form = PostForm(instance=post)

        #Pass form and data ID to Template when loading page
        return render(request,
                      'sample_app/post_form.html',  #Template to call
                      {'form': form, 'post_id': post_id})  #Data to pass to Template

    #When the execute button is pressed
    elif request.method == 'POST':
        #Create form with POSTed data
        form = PostForm(request.POST, instance=post)

        #Validation of input data
        if form.is_valid():
            #If there is no problem with the check result, update the data
            post = form.save(commit=False)
            post.save()

        #When the execute button is pressed, the process is executed and then redirected to the list screen.
        return redirect('sample_app:read_post')


def delete_post(request, post_id):
    #Get the target object
    post = get_object_or_404(Post, pk=post_id)
    post.delete()

    #At the time of deletion request, redirect to the list display screen after executing deletion
    return redirect('sample_app:read_post')


class PostForm(ModelForm):
    """
Form definition
    """
    class Meta:
        model = Post
        #fields is models.Variable name defined in py
        fields = ('name', 'micropost')

To briefly explain, it is as follows. (If you can see the code, you can skip it.)

create_post() This function is called the data creation process. The process when the page is loaded or when the execute button is pressed is branched by request.method.

When the page loads, a new Post object is used to generate the form. Form definition is defined separately in class. You can easily implement a form using the standard Django ModelForm.

When the execute button is pressed, the Post object is created using the value entered in the form. This is creating new data. We also validate the input data. This is also easy to implement using the standard Django feature form.is_valid.

After the creation process, it is skipped to the data list screen.

read_post() This function is called as a process to display a data list. All you have to do is fetch all the data from the database and pass it directly to the Template.

edit_post() This function is called data editing process. Similar to the creation process, but it gets a Post object and creates a form with the id passed as an argument.

The get_object_or_404 used in the function is a very useful standard Django feature. It is a function to get an object, but if there is no target object, it will send a 404Error. This will prevent you from inadvertently issuing a Server Error (500).

The process when the execute button is pressed is the same as Data creation process.

delete_post() This function is called the data deletion process. The Post object is fetched and the target object is deleted by the id passed as an argument.

The deletion process does not pass data to Template, and redirects to the data list screen after executing the process.

By defining each process in View in this way, application functions can be implemented.

Creating Template

Next, create a ** Template (definition of display) **.

Template defines the screen display. After all, it's an html file.

Django has a fixed location for Templates.

Create a two-level directory under my_project/sample_app / Prepare a directory called my_project/sample_app/templates/sample_app /.

Here, we will create a Template to be used in the application.

This time, you need the following two templates.

-** Data list screen ** -** Data entry form screen **

Data list screen

Create my_project/sample_app/templates/sample_app/post_list.html.

post_list.html


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Post lists</title>
</head>
<body>
  <table>
    <thead>
      <tr>
        <th>ID</th>
        <th>User Name</th>
        <th>Post</th>
      </tr>
    </thead>
    <tbody>
      {% for post in posts %}
      <tr>
        <th>{{ post.id }}</th>
        <td>{{ post.name }}</td>
        <td>{{ post.micropost }}</td>
        <td>
          <a href="{% url 'sample_app:edit_post' post_id=post.id %}">Fix</a>
          <a href="{% url 'sample_app:delete_post' post_id=post.id %}">Delete</a>
        </td>
      </tr>
      {% endfor %}
    </tbody>
  </table>
  <a href="{% url 'sample_app:create_post' %}">Create</a>
</body>
</html>

This Template is called from View's read_post ().

The important parts are as follows.

    <tbody>
      {% for post in posts %}
      <tr>
        <th>{{ post.id }}</th>
        <td>{{ post.name }}</td>
        <td>{{ post.micropost }}</td>
        <td>
          <a href="{% url 'sample_app:edit_post' post_id=post.id %}">Fix</a>
          <a href="{% url 'sample_app:delete_post' post_id=post.id %}">Delete</a>
        </td>
      </tr>
      {% endfor %}
    </tbody>

We are now looping through the posts received from View. This is displaying as many table rows as there are data.

Data entry form screen

Create my_project/sample_app/templates/sample_app/post_form.html.

post_form.html


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Post Form</title>
</head>
<body>
    <h4>Editing Post</h4>
    {% if post_id %}
    <form action="{% url 'sample_app:edit_post' post_id=post_id %}" method="post">
    {% else %}
    <form action="{% url 'sample_app:create_post' %}" method="post">
    {% endif %}
      {% csrf_token %}
      {{ form }}
          <button type="submit">Send</button>
    </form>
    <a href="{% url 'sample_app:read_post' %}">Return</a>
</body>
</html>

This Template is called from View's create_post () and edit_post ().

Therefore, form action is branched depending on the presence or absence of post_id as shown below.

    {% if post_id %}
    <form action="{% url 'sample_app:edit_post' post_id=post_id %}" method="post">
    {% else %}
    <form action="{% url 'sample_app:create_post' %}" method="post">
    {% endif %}

With the above, the Template has been created.

After that, if you define the routing, it should work as an application.

Routing definition

Finally, let's define the routing.

Routing is ** "linking URL and processing" **.

In other words, when you access http://127.0.0.1:8000/sample_app/post/create/, Let's define something like calling create_post () in View ...

This time, we will link as follows.

--Data creation: http://127.0.0.1:8000/sample_app/post/create/ --Data editing: http://127.0.0.1:8000/sample_app/post/edit/1/ --Data list: http://127.0.0.1:8000/sample_app/post/ --Data deletion: http://127.0.0.1:8000/sample_app/post/delete/1/

Let's make it.

Create a new file called my_project/sample_app/urls.py.

my_project/sample_app/urls.py


from django.urls import path
from sample_app import views


app_name = 'sample_app'
urlpatterns = [
    path('post/create/', views.create_post, name='create_post'),  #Create
    path('post/edit/<int:post_id>/', views.edit_post, name='edit_post'),  #Fix
    path('post/', views.read_post, name='read_post'),   #List display
    path('post/delete/<int:post_id>/', views.delete_post, name='delete_post'),   #Delete
]

Next, load the created my_project/sample_app/urls.py in my_project/urls.py for the entire project.

my_project/urls.py


from django.contrib import admin
from django.urls import path, include   # Add


urlpatterns = [
    path('sample_app/', include('sample_app.urls')),   # Add
    path('admin/', admin.site.urls),
]

This will allow your project to recognize the application URL. By the way, name ='XXX' can be anything. (I try to align it with the function name)

Complete

If you can implement it so far, it should work as an application.

Let's run python manage.py runserver again.

$ python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
December 20, 2020 - 09:12:49
Django version 3.1.4, using settings 'my_project.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

In this state, if you access http://127.0.0.1:8000/sample_app/post/ from your browser, the data list display screen will be displayed.

2.png

It also has a create button and a modify button, so you can create data and modify or delete the created data.

3.png

4.png

at the end

Thank you for reading to the end. How was that.

Once you have created such an application feature ** Design with css, deploy to heroku, get your own domain, and you have a web service **.

The creation of Web services is summarized in the following article.

-I want to publish the product at the lowest cost -Web service made for several tens of yen

Have a good Django life next year!

Recommended Posts

If you know Python, you can make a web application with Django
Build a web application with Django
[Python] A quick web application with Bottle!
Run a Python web application with Docker
Let's make a web framework with Python! (1)
Let's make a web framework with Python! (2)
I made a WEB application with Django
You can easily create a GUI with Python
[Streamlit] I hate JavaScript, so I make a web application only with Python
If you want to make a TODO application (distributed) now using only Python
(Python) Try to develop a web application using Django
Launch a Python web application with Nginx + Gunicorn with Docker
Web application creation with Django
Web application made with Python3.4 + Django (Part.1 Environment construction)
Make a fortune with Python
A memo about building a Django (Python) application with Docker
Web application with Python + Flask ② ③
If you want to make a discord bot with python, let's use a framework
Web application with Python + Flask ④
If you want to make a Windows application (exe) that can be actually used now using only Python
You can create an interactive web application with Python alone [Strength finder dashboard creation]
Create a web API that can deliver images with Django
Let's make a GUI with python.
Deploy a Django application with Docker
Make a recommender system with python
Make a filter with a django template
Let's make a graph with python! !!
Python | What you can do with Python
[Python] Make a graph that can be moved around with Plotly
Let's make a WEB application for phone book with flask Part 1
Let's make a WEB application for phone book with flask Part 2
I tried to make a 2channel post notification application with Python
Let's make a WEB application for phone book with flask Part 3
Make a scraping app with Python + Django + AWS and change jobs
I tried to make a todo application using bottle with python
Let's make a WEB application for phone book with flask Part 4
Check if you can connect to a TCP port in Python
Launched a web application on AWS with django and changed jobs
Let's make a web chat using WebSocket with AWS serverless (Python)!
Let's make a shiritori game with Python
Daemonize a Python web app with Supervisor
Let's make a voice slowly with Python
If you make 1 billion private keys, you can make a public key including your name with high probability.
Make a desktop app with Python with Electron
Let's make a Twitter Bot with Python!
Until you can use opencv with python
[Python] To get started with Python, you must first make sure you can use Python.
[GCP] Procedure for creating a web application with Cloud Functions (Python + Flask)
Until you publish (deploy) a web application made with bottle on Heroku
I want to make a web application using React and Python flask
Implement a simple application with Python full scratch without using a web framework.
Make a Twitter trend bot with heroku + Python
I made a GUI application with Python + PyQt5
[Python] Make a game with Pyxel-Use an editor-
I want to make a game with Python
Start a simple Python web server with Docker
[Python] Build a Django development environment with Docker
Try to make a "cryptanalysis" cipher with Python
Steps to develop a web application in Python
[Python] Make a simple maze game with Pyxel
Launch a web server with Python and Flask