TL;DR Continuation of Amateur infrastructure engineer touches Django with Docker (1): Make Django with Docker. I will create a model in django that I made last time. There is a site called Django Girls that has a tutorial on django, so this time I will sample the blog according to the chapters after "Django model" of it. Play with django while creating it. (This site is very easy to understand, and honestly it may be better than looking at this post, but by disclosing the learning process and research when an amateur touched it, people of the same level I am writing with the aim of promoting understanding.)
Model - Template - View Django seems to be designed with the idea of MTV (model template view). I've heard of MVC (Model View Controller) (only the name). .. Check one by one.
Model The model interacts with the database. In the DjangoGirls blog example, after mentioning object orientation, the following is listed as necessary data for the blog.
Post
--------
title
text
author
created_date
published_date
Such a data format that will be needed is defined as a model, and when a request comes, the required data is fetched from the DB and returned. This seems to be about the same as Model's role in MVC. (Perhaps)
Template Templates in Django refer to the good looking part. That is html and CSS and javascript to complement it. In MVC, the role of View. It's complicated. .. In MVC, the Controller bridges the Model and View, and the Template in MTV does not get data directly from the Model. Be sure to handle data through View.
View As I mentioned a little in Template, View describes how to show the information acquired by using Model. After that, it is made into a function and linked with Template. In other words, as a role, ① Issue a data acquisition command to Model ② Determine the Template to be returned to the user's request ③ Pass the data obtained from Model to Template as a function There are three. (I'm not very confident, but if I make a mistake, I'll fix it, so please point it out.) When a user visits a website made with django, first decide which View function to process according to the description in urls.py, and the selected View function uses Model to get the data and use it as the selected template. Display the web page after passing the data.
Is the image somehow like the following? U ⇒ urls.py ⇒ view.py ⇔ Model ⇔ DB S ⇓ E ⇓ R ⇐ Templates
With a soft awareness of these three roles, proceed to construction.
manage.py startapp
docker-compose run web python manage.py startapp blog
Create an application template in the local environment using docker-compose.yaml created last time. Last time, manage.py was used for runserver to start web server, but startapp will create the files necessary to create a model. The directory structure after executing this command, including the previous execution, should be as follows.
.
∟ blog
∟ admin.py
∟ apps.py
∟ __init__.py
∟ migrations
∟ models.py
∟ tests.py
∟ views.py
∟ composeexample
∟ __init__.py
∟ __pycache__
∟ settings.py
∟ urls.py
∟ wsgi.py
∟ docker-compose.yaml
∟ Dockerfile
∟ manage.py
∟ migrations
∟ requirements.txt
As before, if you run it on a linux machine, the folder permissions will be root, so do the following:
sudo chown -R $USER:$USER .
settings.py
settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog',
]
Add the application created this time to INSTALLED_APPS.
models.py
blog/models.py
from django.conf import settings
from django.db import models
from django.utils import timezone
class Post(models.Model):
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
title = models.CharField(max_length=200)
text = models.TextField()
created_date = models.DateTimeField(default=timezone.now)
published_date = models.DateTimeField(blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.title
Create a model definition. There is models.py in the blog folder created by startapp, so edit it. From the beginning, only the second line, from django.db import models
, is borrowed, and the Django Girls sample is borrowed.
from django.conf import settings
Module used when referencing variables in project / settings.py
.
from django.db import models
A module that provides various methods for model. Foreign keys, data types, etc.
from django.utils import timezone
Module about time zone. It's almost the same as the utility provided in various languages. This time I'm using it to get the time at the time of posting. Since the timezone is set in settings.py, it should be UTC in the current situation where nothing is done.
class Post(models.Model):
The part that defines the model called Post. The model to be defined is created by inheriting django.db.models.Model. It is also possible to create child classes. For example, create_date may be used in other models for general purposes, so create a Timestamp class that defines create_date data and inherit it in the form of Post (Timestamp).
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
ForeignKey () defines a model that is a foreign key. This time, in order to specify the User model that django has by default as a foreign key, the MODEL definition is acquired using the settings module, but if you normally use the model you created as a foreign key, the model Specify the name. The on_delete option is required in django 2.0 or later, and specifies the behavior when a foreign key object is deleted. CASCADE deletes all associated objects when it deletes a foreign key object.
title = models.CharField(max_length=200)
text = models.TextField()
created_date = models.DateTimeField(default=timezone.now)
published_date = models.DateTimeField(blank=True, null=True)
Specify the data types and constraints that make up the blog. For created_date, the time when the object was created is entered. That is, the time when the article was written. On the other hand, published_date is blank at the moment, and the value is entered in the publish method described later.
def publish(self):
self.published_date = timezone.now()
self.save()
A method for publishing blog articles. The current time is assigned to published_date, which is the published time, and the save () method is called. I don't remember writing the save () method, so of course, in the method in the inheritance source models.Model, if the primary key exists in the table, UPDATE and if it does not exist, CREATE it.
def __str__(self):
return self.title
magic method. (Because it is not the main point about the magic method, please check it yourself.) The title of the blog article is returned when it is instantiated.
In django, creating a table in the database connected with the contents of models.py seems to be called migration.
When you execute the command manage.py makemigrations
, a file for migration is created, and the command manage.py migrate
actually creates a table on the database.
Immediately enter the web server with docker-compose exec
, execute the command, enter the db server and check if the table is created. (These operations will be added to the command in docker-compose later so that migration will be performed with docker-compose up
, but now I am entering the container and executing the command for confirmation)
docker-compose exec web bash
(Hereafter in the web container)
manage.py makemigrations blog
The following output is output. blog/migrations/0001_initial.py
manaeg.py migrate blog
Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying blog.0001_initial... OK If the output is as above, the migration is complete. Exit the web server with exit and enter the db server to check.
docker-compose exec db bash
(Hereafter in the db container)
psql -U postgres
\d
\d Execution result
List of relations
Schema | Name | Type | Owner
--------+-----------------------------------+----------+----------
public | auth_group | table | postgres
public | auth_group_id_seq | sequence | postgres
public | auth_group_permissions | table | postgres
public | auth_group_permissions_id_seq | sequence | postgres
public | auth_permission | table | postgres
public | auth_permission_id_seq | sequence | postgres
public | auth_user | table | postgres
public | auth_user_groups | table | postgres
public | auth_user_groups_id_seq | sequence | postgres
public | auth_user_id_seq | sequence | postgres
public | auth_user_user_permissions | table | postgres
public | auth_user_user_permissions_id_seq | sequence | postgres
public | blog_post | table | postgres
public | blog_post_id_seq | sequence | postgres
public | django_content_type | table | postgres
public | django_content_type_id_seq | sequence | postgres
public | django_migrations | table | postgres
public | django_migrations_id_seq | sequence | postgres
There are many tables. auth and django are probably created by default (probably). Since I wrote blog_post in models.py, check the definition of the blog_post table.
\d blog_post
\d Execution result
Table "public.blog_post"
Column | Type | Collation | Nullable | Default
----------------+--------------------------+-----------+----------+---------------------------------------
id | integer | | not null | nextval('blog_post_id_seq'::regclass)
title | character varying(200) | | not null |
text | text | | not null |
created_date | timestamp with time zone | | not null |
published_date | timestamp with time zone | | |
author_id | integer | | not null |
Indexes:
"blog_post_pkey" PRIMARY KEY, btree (id)
"blog_post_author_id_dd7a8485" btree (author_id)
Foreign-key constraints:
"blog_post_author_id_dd7a8485_fk_auth_user_id" FOREIGN KEY (author_id) REFERENCES auth_user(id) DEFERRABLE INITIALLY DEFERRED
id is a serial number given by default when django defines a model, and is the primary key. Others are as defined in models.py. The model is now ready.
It feels like the second step at last, but let's do it without fail. ..
Recommended Posts