[PYTHON] Things to do when you start developing with Django

Introduction

What you should do when you start developing with Django. It will be difficult to change it later, so it may be better to set it at the initial stage, though not always. ** Create "Settings directory name settings containing settings.py" ** and ** "Extended user model" **.

There may be many other things, but as a memorandum at this stage.

Who is the target of this article

――People who have just finished Django's tutorial-like teaching materials and are about to start making apps. --People who want to organize basic knowledge about directory structure, projects, and applications --People who want to customize the user model a little

(1) Rename the setting directory when creating the project

This is a measure to make the directory structure of the project easier to understand. If you normally start project creation as $ django-admin startproject myproject, the base directory name and the setting directory name will be created with the same name (myproject in this case), so it will be difficult to distinguish between them. I will.

What this means is that when you start creating a project with this command, you will have a directory structure like this.

myproject   <-Base directory
|-- manage.py
`-- myproject  <-Settings directory
    |-- __init__.py
    |-- settings.py
    |-- urls.py
    |-- manage.py
    `-- wsgi.py

There is a base directory with the same name as the project name (myproject in this case), and a setting directory with the same name is created in it. (By the way, the Django textbook that can be used in the field << Basics >>](https://www.amazon.co.jp/%E7%8F%BE%E5%A0%B4%E3%81] % A7% E4% BD% BF% E3% 81% 88% E3% 82% 8B-Django-% E3% 81% AE% E6% 95% 99% E7% A7% 91% E6% 9B% B8% E3% 80% 8A% E5% 9F% BA% E7% A4% 8E% E7% B7% A8% E3% 80% 8B-% E6% A8% AA% E7% 80% AC-% E6% 98% 8E% E4% BB% 81 / dp / 4802094744) makes it easy to distinguish

--Base directory = project directory created by django-admin startproject --Settings directory = Directory with settings.py

Since it is called, I will follow that name)


So, there is a way to rename the settings directory to make the structure easier to understand.

When creating a project, create a base directory with an arbitrary name (project name), move it under the base directory, specify the setting directory name (here config) in the first argument, and specify . in the second argument. Then run start project.

$mkdir myproject (enter the project name here)
$ cd myproject/
$ django-admin startproject config .

By doing this, the directory structure

myproject   <-Base directory
|-- manage.py
`-- config  <-Settings directory*This name changes
    |-- __init__.py
    |-- settings.py
    |-- urls.py
    |-- manage.py
    `-- wsgi.py

This is how the structure is easy to understand.

(2) Expand the user model

Django comes with a User model by default, making it easy to implement things like login. That alone is very convenient, but to make the User model easier to use, it is recommended to create a customized user model [officially recommended](https://docs.djangoproject.com/ja/2.0/topics/ auth / customizing / # using-a-custom-user-model-when-starting-a-project).

There are three main ways to extend the User model,

  1. Inherit ʻAbstractBaseUser`
  2. Inherit ʻAbstractUser`
  3. Make another model and associate it with ʻOneToOneField`

Each method has its advantages and disadvantages, If development progresses and there is already data in the database, method 3 seems to be good. 1 or 2 is recommended at the first stage of starting application production, but 1 seems to be difficult for beginners to beginners, so it is safe to get used to method 2 at first.

Method 2 allows you to add your own columns to your user model.

It's easy to create a custom user model.

① Described in ʻapp / models.py (ʻapp is the application directory name) (2) Set ʻAUTH_USER_MODEL in config / settings.py (config` is the name of the setting directory created when the project is created) ③ Migrate

① Described in `models.py``

Define a custom user model here. (Since the information that is the basis of the user model is defined in the model called ʻAbstractUser`, it will be inherited and used.)

Here you can specify the table name and the columns you want to add. For example, you can set a table called custome_user with a column called Calendar with a foreign key.

app/models.py


from django.contrib.auth.models import AbstractUser
from django.db import models

class CustomUser(AbstractUser):
    class Meta(AbstractUser.Meta):
        db_table = 'custom_user'
        swappable = 'AUTH_USER_MODEL'

    calendar = models.ForeignKey(Calendar, verbose_name='Active calendar', on_delete=models.PROTECT, blank=True, null=True)

Since this is an example of my actual code, I have linked a model called Calendar to the user model, but if you want the user model to have gender, age, email address, password, etc., specify the column here. I think you should give it to me. Since the column is added to the default User model, the original column remains (see MEMO at the end of this article for the contents of the default User model).

② Set ʻAUTH_USER_MODEL in settings.py`

Define the custom user model to use here. Describe as "app name.model name"

config/settings.py


AUTH_USER_MODEL = app.CustomUser

③ Migrate

If you change the model, you can migrate the standard database.

$ Python manage.py makemigrations
$ Python manage.py migrate

Various for getting started with Django

About version

Regarding which version to specify, there seems to be no mistake if you adopt the version that corresponds to ** LTS (Long-Term Support) ** (= version with long-term security support).

--2.2 => Support until April 2022 --1.11 => Support until April 2020

By the way, the Django 3 series was released in December 2019, but 3.2, which corresponds to LTS, is scheduled to be released in April 2021.

If there is no particular reason, is it correct to start with the latest LTS at the moment? It is an impression. (If the deployment destination is decided, it may be necessary to investigate whether the server supports it etc.)

About projects and applications

Django has the concept of "project" and "application", so let's sort it out a bit.

project The whole WEB application to be produced. $ django-admin startproject myproject The one created by the command (myproject is the project name)     application A group of small functions that belong to a project python3 manage.py startapp myapp The one created by the command (myapp is the application name)


The project is a big box, and the application is an image created by each function in the box.

When creating one WEB service, create one project, and if it is a small service, create one application in it and implement it. As the scale of a project grows, it is possible to create and operate multiple applications in one project.

--Applications should be made as independent as possible from other applications --The basic style is to add functions by adding applications to the project one after another.

When creating multiple applications, it seems that maintenance is easier if you consider this.

in conclusion

After finishing the tutorial-like teaching materials, I introduced it on the way.

[Django textbooks that can be used in the field << Basics >>](https://www.amazon.co.jp/%E7%8F%BE%E5%A0%B4%E3%81%A7%E4%BD%BF% E3% 81% 88% E3% 82% 8B-Django-% E3% 81% AE% E6% 95% 99% E7% A7% 91% E6% 9B% B8% E3% 80% 8A% E5% 9F% BA % E7% A4% 8E% E7% B7% A8% E3% 80% 8B-% E6% A8% AA% E7% 80% AC-% E6% 98% 8E% E4% BB% 81 / dp / 4802094744)

This book is very easy to understand and makes your study progress!

The basics are widely covered and are good for knowledge retention and understanding. You can read while eating a pinch. Many of the best practice methods summarized this time are posted, and it is quite useful.

MEMO: About the default User model

For reference, the fields of the User model confirmed in Django 2.1.7 are listed. Since the default User model inherits from the AbstractUser model, the column names of the AbstractUser model will be inherited when you create a custom user model.

lib/django/contrib/auth/models.py


class AbstractUser(AbstractBaseUser, PermissionsMixin):
    """
    An abstract base class implementing a fully featured User model with
    admin-compliant permissions.

    Username and password are required. Other fields are optional.
    """
    username_validator = UnicodeUsernameValidator()

    username = models.CharField(
        _('username'),
        max_length=150,
        unique=True,
        help_text=_('Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.'),
        validators=[username_validator],
        error_messages={
            'unique': _("A user with that username already exists."),
        },
    )
    first_name = models.CharField(_('first name'), max_length=30, blank=True)
    last_name = models.CharField(_('last name'), max_length=150, blank=True)
    email = models.EmailField(_('email address'), blank=True)
    is_staff = models.BooleanField(
        _('staff status'),
        default=False,
        help_text=_('Designates whether the user can log into this admin site.'),
    )
    is_active = models.BooleanField(
        _('active'),
        default=True,
        help_text=_(
            'Designates whether this user should be treated as active. '
            'Unselect this instead of deleting accounts.'
        ),
    )
    date_joined = models.DateTimeField(_('date joined'), default=timezone.now)

    objects = UserManager()

    EMAIL_FIELD = 'email'
    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['email']

    class Meta:
        verbose_name = _('user')
        verbose_name_plural = _('users')
        abstract = True

    def clean(self):
        super().clean()
        self.email = self.__class__.objects.normalize_email(self.email)

    def get_full_name(self):
        """
        Return the first_name plus the last_name, with a space in between.
        """
        full_name = '%s %s' % (self.first_name, self.last_name)
        return full_name.strip()

    def get_short_name(self):
        """Return the short name for the user."""
        return self.first_name

    def email_user(self, subject, message, from_email=None, **kwargs):
        """Send an email to this user."""
        send_mail(subject, message, from_email, [self.email], **kwargs)


class User(AbstractUser):
    """
    Users within the Django authentication system are represented by this
    model.

    Username and password are required. Other fields are optional.
    """
    class Meta(AbstractUser.Meta):
        swappable = 'AUTH_USER_MODEL'

Recommended Posts

Things to do when you start developing with Django
Things to watch out for when migrating with Django
[AWS] What to do when you want to pip with Lambda
How to do arithmetic with Django template
[Tips] How to do template extends when creating HTML with django
Start today with Django
Things to keep in mind when developing crawlers in Python
Settings when you want to run python-mecab with travis
Links to do what you want with Sublime Text
When writing a test using DB with django, you may be able to do it faster by using `setUpTestData ()`
What to do when you can't bind CaboCha to Python
A story that required preparation when trying to do a Django tutorial with plain centos7
What to do if you get an OpenSSL error when installing Python 2 with pyenv
What to do if you get an Import Error when importing matplotlib with Jupyter
Do Django with CodeStar (Python3.8, Django2.1.15)
Do AES encryption with DJango
Solution when you want to use cv_bridge with python3 (virtualenv)
[Django] A memorandum when you want to communicate asynchronously [Python3]
How to handle static files when deploying to production with Django
Knowledge you need to know when programming competitive programming with Python2
A solution when you can't start project Django on Windows
Use aggdraw when you want to draw beautifully with pillow
How to resolve CSRF Protection when using AngularJS with Django
What to do if you can't sort files with subscripts
What to do when an error occurs with import _ssl
When you want to register Django's initial data with relationships
Things to keep in mind when using Python with AtCoder
Things to keep in mind when using cgi with python.
ImportError: No module What to do when you are told
[Memo to add] Page to see when developing with GAE / P
I know? Data analysis using Python or things you want to use when you want with numpy
What to do if you get an Undefined error when trying to use pip with pyenv
What to do when Ubuntu crashes
Steps to develop Django with VSCode
If you want to become a data scientist, start with Kaggle
How to deal with "You have multiple authentication backends configured ..." (Django)
Until you start Jupyter with Docker
What to do with Magics install
What to do if you can't install pyaudio with pip #Python
Nice to meet you with python
When it is troublesome to copy what you built with vue
[Beanstalk] What to do when an error occurs with import uuid
Common html to rent with Django
When you want to print to standard output with print while testing with pytest
Prevent unnecessary directories from being created under the current directory when you start project with Django
To do tail recursion with Python2
What to do if you get a UnicodeDecodeError with pip install
What to do with PYTHON release?
When WSL Distro fails to start (error: "WslRegisterDistribution failed with error: 0x800706be.")
When you want to send an object with requests using flask
I want to do ○○ with Pandas
What to do if you can't build your project with Maven
What to do when you get "I can't see the site !!!!"
Python | What you can do with Python
How to authenticate with Django Part 2
When you want to adjust the axis scale interval with APLpy
How to authenticate with Django Part 3
What to do if you get a "Wrong Python Platform" warning when using Python with the NetBeans IDE
What to do when you get angry that libxml / xmlversion.h does not exist when you put lxml with pip
What to do if you can't find well with grep's -f option
I want to do it with Python lambda Django, but I will stop