[PYTHON] Tipps zum Django Rest Framework

Versionsinformation

module version
Python 3.7.7
django-environ 0.4.5
Django 2.2.11
djangorestframework 3.11.0
djangorestframework-jwt 1.11.0
django-rest-swagger 2.2.0
django-filter 2.2.0
mysqlclient 1.4.6

Ich möchte Swagger verwenden

Installieren Sie den Django-Rest-Swagger mit Pip

pip3 install django-rest-swagger==2.2.0

Ändern Sie settings.py

backend/src/config/settings/settings.py


.
..
...
REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication',
    )
}

Behoben: development.py

backend/src/config/settings/developement.py


.
..
...
INSTALLED_APPS += [
    'rest_framework_swagger',
]

REST_FRAMEWORK['DEFAULT_SCHEMA_CLASS'] = 'rest_framework.schemas.coreapi.AutoSchema'

URLs.py behoben

backend/src/config/urls.py


from django.contrib import admin
from django.urls import path
from django.conf import settings  #Nachtrag
from rest_framework_jwt.views import obtain_jwt_token  #Nachtrag

urlpatterns = [
    path('admin/', admin.site.urls),
    url('api/v1/login/', obtain_jwt_token),  #Swagger ohne eine oder mehrere APIs-Es scheint, dass die Benutzeroberfläche nicht geöffnet werden kann. Registrieren Sie daher vorerst die Anmelde-API
]

#Fügen Sie alle unten hinzu
if settings.DEBUG:  # DEBUG=Wird nur verwendet, wenn True (während der Entwicklung)
    from rest_framework.schemas import get_schema_view
    from rest_framework_swagger import renderers
    schema_view = get_schema_view(
        title='API-Liste',
        public=True,
        renderer_classes=[renderers.OpenAPIRenderer, renderers.SwaggerUIRenderer])
    urlpatterns += [
        url(API_ROOT + 'api-auth/', include('rest_framework.urls')),
        url('swagger-ui/', schema_view),
    ]

Greifen Sie auf Swagger-ui zu

Greifen Sie auf http://0.0.0.0:8000/swagger-ui/ zu. Wenn der folgende Bildschirm angezeigt wird, klicken Sie oben rechts auf "Anmelden" Drücken Sie, um sich anzumelden image.png

image.png

image.png

Sätze anzeigen

Ich möchte vorerst die API von GET, POST, PUT, DELETE ... für das Modell veröffentlichen

Sie können die "ModelViewSets" verwenden, die jeder liebt.

backend/src/api/users/views.py


from api.users.serializers import UserSerializer
from common.models import User
from rest_framework.viewsets import ModelViewSet  #Dies


class UserViewSets(ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

Fertig (mit swagger-ui) image.png

Ich möchte die zu veröffentlichenden HTTP-Anforderungsmethoden eingrenzen

Methode 1: Kombinieren Sie GenericViewSet mit verschiedenen Mixins

Wenn Sie die Anzahl der Anforderungsmethoden später erhöhen möchten, fügen Sie die entsprechenden Mixins hinzu.

backend/src/api/users/views.py


from api.users.serializers import UserSerializer
from common.models import User
from rest_framework.viewsets import GenericViewSet  #Dies
from rest_framework.mixins import CreateModelMixin  #Dies


class UserViewSets(GenericViewSet, CreateModelMixin):
    queryset = User.objects.all()
    serializer_class = UserSerializer

image.png

Methode 2: Verwenden Sie Generika

Wenn Sie die Anzahl der Anforderungsmethoden später erhöhen möchten, können Sie die entsprechende APIView hinzufügen.

backend/src/api/users/views.py


from api.users.serializers import UserSerializer
from common.models import User
from rest_framework.generics import CreateAPIView  #Dies


class UserViewSets(CreateAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer

Bei Generika unterscheidet sich die Methode zur Angabe von urls.py

backend/src/config/urls.py


# =========== viewsets ===========
router = DefaultRouter()
router.register('user', user_views.UserViewSets)  #Bei Viewsets kann der Router verwendet werden

urlpatterns = [
    path('admin/', admin.site.urls),
    url('api/v1/login/', obtain_jwt_token),
    url('', include(router.urls)),
]

backend/src/config/urls.py


# =========== generics ===========
urlpatterns = [
    path('admin/', admin.site.urls),
    url('api/v1/login/', obtain_jwt_token),
    url('user/', user_views.UserViewSets.as_view()),  #als URL-Muster_views()Fügen Sie mit hinzu
]

Das Ergebnis ist das gleiche wie bei Methode 1 image.png

Ich möchte ModelViewSet verwenden, aber ich möchte die HTTP-Anforderungsmethode eingrenzen (siehe).

Für solch eine egoistische Person ist es "http_method_names". Ich frage mich, ob es in Situationen verwendet wird, in denen ich es implementiert habe, es aber noch nicht veröffentlichen möchte.

backend/src/api/users/views.py


from api.users.serializers import UserSerializer
from common.models import User
from rest_framework.viewsets import ModelViewSet


class UserViewSets(ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    http_method_names = ['get', 'post']  #Die HTTP-Anforderungsmethode ist klein (wichtig) und nicht groß geschrieben

image.png

Ich möchte API-Anforderungen nur auf authentifizierte Benutzer beschränken

Geben Sie in der Berechtigungsklasse "IsAuthenticated" an.

Ändern Sie zunächst settings.py.

backend/src/config/settings/settings.py


.
..
...
REST_FRAMEWORK = {
    #hinzufügen
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
        # 'common.permissions.IsSuperuser',  #Wenn Sie Ihre eigene Berechtigung erstellt haben, fügen Sie sie hier hinzu.
    ),
    ...
    ..
    .
}

Wenn Sie die API im nicht authentifizierten Zustand anfordern, wird "403" zurückgegeben.

backend/src/api/users/views.py


from api.users.serializers import UserSerializer
from common.models import User
from rest_framework.permissions import IsAuthenticated  #hinzufügen
from rest_framework.viewsets import ModelViewSet


class UserViewSets(ModelViewSet):
    permission_classes = [IsAuthenticated,]  #hinzufügen
    queryset = User.objects.all()
    serializer_class = UserSerializer

Ich möchte eine routingfähige Ad-hoc-Methode hinzufügen (Detail = False).

In einem solchen Fall ist es ein "@ action" -Dekorator. (Wenn die DRF-Version alt ist, ist dies der Dekorator "@ list_route" oder "@ detail_route". Es scheint, dass er in den Dekorator "@ action" integriert wurde.)

backend/src/api/users/views.py


from api.users.serializers import UserSerializer
from common.models import User
from rest_framework.decorators import action  #hinzufügen
from rest_framework.viewsets import ModelViewSet


class UserViewSets(ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

    @action(detail=False, methods=['get'], url_path='get_user', url_name='get_user')
    def get_user(self, request, *kwargs):
        """Gibt Anmeldebenutzerinformationen zurück
        """
        return UserSerializer(self.request.user).data

image.png

Ich möchte eine routingfähige Ad-hoc-Methode hinzufügen (Detail = True).

backend/src/api/users/views.py


from api.users.serializers import UserSerializer
from common.models import User
from rest_framework import status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet


class UserViewSets(ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

    @action(detail=True, methods=['get'], url_path='get_user', url_name='get_user')
    def get_user(self, request, pk=None, **kwargs):
        """Gibt Anmeldebenutzerinformationen zurück
        """
        #Der Prozess ist gescheitert=Gleich wie falsch. Es tut mir Leid(. _ .)
        return Response(
            status=status.HTTP_200_OK,
            data=UserSerializer(self.request.user).data)

Es wird eine API wie api_root / {pk} / url_name / sein. image.png

Ich möchte eine routingfähige Ad-hoc-Methode hinzufügen. Ich möchte den Primärschlüssel in die URL aufnehmen, aber das Detail des @ action-Dekorators sollte False sein (siehe).

Solche Selbstsucht ist "@ action" Dekorateur "url_path".

backend/src/api/users/views.py


from api.users.serializers import UserSerializer
from common.models import User
from rest_framework import status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet


class UserViewSets(ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

    @action(detail=False, methods=['get'], url_path='get_user/(?P<user_id>[0-9]+)', url_name='get_user')
    def get_user(self, request, user_id=None):
        """Gibt Anmeldebenutzerinformationen zurück
        """
        return Response(
            status=status.HTTP_200_OK,
            data=UserSerializer(self.request.user).data)

Es kann für diejenigen empfohlen werden, die die von detail = True lol generierte URL nicht mögen

image.png

Ich möchte nach Abfrageparametern suchen können

Installieren Sie den Django-Filter mit Pip

pip3 install django-filter==2.2.0

Erstellen Sie filter.py (Dateiname ist beliebig) und definieren Sie Filter

backend/src/api/users/filters.py


from common.models import User
from django_filters import FilterSet


class UserSearchFilter(FilterSet):
    class Meta:
        model = User
        fields = '__all__'

        #Felder, die nicht im Abfrageparameter angegeben werden sollen, sollten zum Ausschließen hinzugefügt werden.
        # exclude = [
        #     'password',
        #     'date_created',
        #     'date_updated',
        # ]

Verwenden Sie den definierten Filter in Ansichten

backend/src/api/users/views.py


from api.users.serializers import UserSerializer
from common.models import User
from django_filters.rest_framework import DjangoFilterBackend  #hinzufügen
from api.users.filters import UserSearchFilter  #hinzufügen
from rest_framework.viewsets import ModelViewSet


class UserViewSets(ModelViewSet):
    filter_backends = [DjangoFilterBackend,]  #hinzufügen
    filter_class = UserSearchFilter  #hinzufügen
    queryset = User.objects.all()
    serializer_class = UserSerializer

Sie können die Abfrageparameter angeben und abrufen.

image.png

Serializer Edition

Jeder liebt Model Serializer

backend/src/api/users/serializers.py


from rest_framework.serializers import ModelSerializer
from common.models import User


class UserSerializer(ModelSerializer):
    """Benutzer-Serializer
    """
    class Meta:
        model = User
        fields = '__all__'

Ich möchte die Parameter eingrenzen

Ich möchte keine Gruppen oder Benutzerberechtigungen als Parameter werfen

image.png

In diesem Fall geben Sie es in "extra_kwargs" an.

backend/src/api/users/serializers.py


from rest_framework.serializers import ModelSerializer
from common.models import User


class UserSerializer(ModelSerializer):
    """Benutzer-Serializer
    """
    class Meta:
        model = User
        fields = '__all__'
        extra_kwargs = {
            'is_superuser': {'read_only': True},
            'date_created': {'read_only': True},
            'date_deleted': {'read_only': True},
            'is_staff': {'read_only': True},
            'is_active': {'read_only': True},
            'groups': {'read_only': True},
            'user_permissions': {'read_only': True},
        }

Ich drückte es sicher ↓ image.png

Da es nur schreibgeschützt ist (read_only), enthält es das zum Zeitpunkt der Erfassung (GET) in "extra_kwargs" angegebene. image.png

Ich möchte das Ergebnis einer Funktion / Methode als Feldwert zurückgeben

Beispielsweise enthält der Wert des Beziehungsziels nur den Primärschlüssel.

In einem solchen Fall können Sie "SerializerMethodField" verwenden. Nach dem Definieren der Felder bereiten wir eine Funktion für get_field name vor.

backend/src/api/users/serializers.py


import json  #hinzufügen
from django.core.serializers import serialize  #hinzufügen
from rest_framework.serializers import ModelSerializer, SerializerMethodField  #hinzufügen
from common.models import User


class UserSerializer(ModelSerializer):
    """Benutzer-Serializer
    """
    school = SerializerMethodField()  #Feld hinzufügen

    # get_Funktion für Feldname hinzugefügt
    def get_school(self, obj):
        """Gibt ein JSON-serialisiertes Objekt des Schulobjekts zurück

        Args:
            obj (User):Benutzerobjekt
        
        Returns:
            dict:Ein Objekt, das das Benutzerobjekt im JSON-Format serialisiert
        """
        if obj.school is not None:
            data = serialize('json', [obj.school,])
            objs = json.loads(data)
            return json.dumps(objs[0]['fields'])
        return None

    class Meta:
        ...

Das Schulobjekt wurde zu "Schule" erweitert, was früher der Hauptschlüssel war (. _.) SerializerMethodField ist praktisch, da es jeden Wert zusammen zurückgeben kann.

image.png

Ich möchte das Objekt zurückgeben, mit dem ich verwandt bin. Aber ich verstehe SerializerMethodField (Teru) nicht

Eine solche Selbstsucht ist eine "Tiefen" -Option.

backend/src/api/users/serializers.py


from common.models import User


class UserSerializer(ModelSerializer):
    """Benutzer-Serializer
    """
    class Meta:
        model = User
        fields = '__all__'
        extra_kwargs = {
            'is_superuser': {'read_only': True},
            'date_created': {'read_only': True},
            'date_deleted': {'read_only': True},
            'is_staff': {'read_only': True},
            'is_active': {'read_only': True},
            'groups': {'read_only': True},
            'user_permissions': {'read_only': True},
        }
        depth = 1  #Der Standardwert ist 0, daher ist es nicht sinnvoll, 0 anzugeben

image.png

Wenn Sie "Tiefe = 2" tun, erhalten Sie noch weitere Beziehungen. (Wenn in diesem Beispiel "Schule" mehr Beziehungen vor sich hat, wird auch dieses Objekt zurückgegeben.)

djangorestframework-jwt edition

Ich möchte Benutzerinformationen zusätzlich zum Token in die Antwort von get_jwt_token aufnehmen

Standardmäßig wird nur "Token" zurückgegeben. image.png

Wenn Sie hier zusätzlich zum Token Benutzerinformationen einfügen möchten, erstellen Sie Ihren eigenen "jwt_response_payload_handler". Erstellen Sie jwt_utils.py (Dateiname ist beliebig)

backend/src/common/jwt_utils.py


def jwt_response_payload_handler(token, user=None, request=None):
    """Benutzerdefinierte Antwort für die JWT-Authentifizierung
    """
    return {
        'token': token,
        'first_login': user.first_login,
        'id': user.id,
    }

Ändern Sie settings.py.

backend/src/config/settings/settings.py


.
..
...
# JWT_AUTH hinzufügen
JWT_AUTH = {
    'JWT_RESPONSE_PAYLOAD_HANDLER': 'common.jwt_utils.jwt_response_payload_handler',  # JWT_RESPONSE_PAYLOAD_Selbstgemachtes JWT für HANDLER_response_payload_Geben Sie den Handler an
}

Ich konnte die Antwort erhöhen (. _.)

image.png

Einführung in das Django-Projekt, Django Rest Framework

Pip-Installation von Django-Environ-, Django- und Djangorest-Framework

pip3 install django-environ==0.4.5 Django==2.2.11 djangorestframework==3.11.0 mysqlclient==1.4.6

Erstellen Sie das Projektstamm- und Backend-Verzeichnis src

mkdir -p project_root/backend/src

Die Verzeichnisstruktur ist wie folgt

project_root #Projektstamm
└── backend
    └── src

Django-Projekterstellung

cd project_root/backend/src
django-admin startproject confing .

Die Verzeichnisstruktur ist wie folgt (Konfigurationsdateien können in config gesammelt werden)

project_root #Projektstamm
└── backend
     └── src
         ├── config
         │    ├── __init__.py
         │    ├── settings.py
         │    ├── urls.py
         │    └── wsgi.py
         │
         └── manage.py

Teilen Sie die Konfigurationsdatei in Entwicklung und Produktion

project_root #Projektstamm
└── backend
     └── src
         ├── config
         │    ├── __init__.py
         │    ├── settings
         │    │    ├── settings.py
         │    │    ├── development.py  #Zur Entwicklung
         │    │    └── production.py  #Für die Produktion
         │    │
         │    ├── urls.py
         │    └── wsgi.py
         └── manage.py

Korrektur aufgrund der Einstellung der Dateiteilung

Ändern Sie settings.py (BASE_DIR wurde als "src" -Verzeichnis korrigiert.)

backend/src/config/settings/settings.py


.
..
...
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))  # >> /src/confing/settings
 │
 ↓
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))  # >> /src
...
..
.

Fix verwalten.py

backend/src/manage.py


.
..
...
def main():
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'confing.settings')
     │
     ↓
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'confing.settings.development')  #Lesen Sie die Entwicklung
...
..
.

Ändern Sie wsgi.py für die Bereitstellung

backend/src/config/wsgi.py


os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'confing.settings')
 │
 ↓
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'confing.settings.production')

Behoben: development.py

backend/src/config/settings/development.py


from confing.settings.settings import *

ALLOWED_HOSTS = ['*']

Ändern Sie product.py

backend/src/config/settings/development.py


from confing.settings.settings import *

DRF verfügbar machen

Ändern Sie settings.py

backend/src/config/settings.settings.py


INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',  #Nachtrag
]

Starten Sie Web- und DB-Container mit Docker

Bereiten Sie docker-compose.yml und Dockerfile vor

project_root #Projektstamm
├── backend
│    ├── src
│    │   ├── config
│    │   │    ├── __init__.py
│    │   │    ├── settings
│    │   │    │    ├── settings.py
│    │   │    │    ├── development.py
│    │   │    │    └── production.py
│    │   │    │
│    │   │    ├── urls.py
│    │   │    └── wsgi.py
│    │   |
│    │   └── manage.py
│    │
│    └── Dockerfile  #hinzufügen
│
└── docker-compose.yml  #hinzufügen

docker-compose.yml


version: '3'
services:
  web:
    build:
      context: ./
      dockerfile: ./backend/Dockerfile
    container_name: drf_web
    volumes:
      - './backend/src:/src'
    environment:
      - LC_ALL=ja_JP.UTF-8
    ports:
      - '8000:8000'
    depends_on:
      - db
    command: python3 manage.py runserver 0.0.0.0:8000
    restart: always
    tty: true

  db:
    image: mariadb:latest
    container_name: drf_db
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci
    environment:
      - MYSQL_ROOT_USER=root
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_DATABASE=db_drf
      - MYSQL_USER=user
      - MYSQL_PASSWORD=user
    volumes:
      - db_data:/var/lib/mysql
    ports:
      - '3306:3306'

volumes:
  db_data:
    driver: local
FROM ubuntu:18.04
RUN apt update && apt install -y locales python3-pip python3.7 python3-dev libssl-dev libffi-dev libgeos-dev libmysqlclient-dev
RUN apt-get update && apt-get install -y mysql-client python3-gdal
RUN mkdir /src \
    && rm -rf /var/lib/apt/lists/* \
    && echo "ja_JP UTF-8" > /etc/locale.gen \
    && locale-gen
WORKDIR /src
ADD ./backend/src /src/
RUN LC_ALL=ja_JP.UTF-8 pip3 install -r requirements.txt

Starten Sie den Docker-Container

docker-compose up -d

Besuchen Sie die Django-Startseite

Erfolg, wenn dieser Bildschirm angezeigt wird image.png

Erstellen Sie eine .env.development-Datei

cd backend/src/
touch .env.development

Inhalt der .env.development-Datei

backend/src/.env.development


DEBUG=True
DATABASE_URL=mysql://user:user@db:3306/db_drf

Behoben: development.py

backend/src/config/settings/development.py


import environ

ENV_FILE = os.path.join(BASE_DIR, '.env.development')
ENV = environ.Env()
ENV.read_env(ENV_FILE)

DEBUG = ENV.get_value('DEBUG', cast=bool)
DATABASES['default'] = ENV.db()  #DB-Verbindungsinformationen lesen (.env.Entwicklung DATENBANK_Liest die URL)
...
..
.

Implementierung des Basismodells

Erstellen Sie eine Basisanwendung

django-admin startapp base

Zu INSTALLED_APPS in settings.py hinzugefügt

INSTALLED_APPS = [
    .
    ..
    ...
    'base',
]

Beschreiben von BaseModel

backend/src/base/models.py


from django.db import models
from django.utils import timezone

# Create your models here.
from django.db import models
from django.utils import timezone

# Create your models here.
class BaseModel(models.Model):
    """Basismodell
    """
    date_created = models.DateTimeField('Erstellungsdatum und -zeit', default=timezone.now)
    date_updated = models.DateTimeField('Zuletzt geändert', auto_now_add=True)
    date_deleted = models.DateTimeField('Datum und Uhrzeit löschen', null=True)

    class Meta:
        abstract = True  #← Erforderlich

Implementierung eines benutzerdefinierten Benutzermodells

Erstellen Sie eine gemeinsame Anwendung

django-admin startapp common

Zu INSTALLED_APPS in settings.py hinzugefügt

INSTALLED_APPS = [
    .
    ..
    ...
    'base',
    'common',
]

Implementieren Sie zuerst den Benutzermanager

Erstellen Sie manager.py

cd backend/src/base
touch manager.py

backend/src/base/manager.py


from django.contrib.auth.models import UserManager


class UserManager(UserManager):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
    
    def _create_user(self, username, email, password, **extra_fields):
        """
        Create and save a user with the given username, email, and password.
        """
        if not username:
            raise ValueError('The given username must be set')
        email = self.normalize_email(email)
        username = self.model.normalize_username(username)
        user = self.model(username=username, email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_user(self, username, email=None, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', False)
        return self._create_user(username, email, password, **extra_fields)

    def create_superuser(self, username, email, password, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError('Superuser must have is_staff=True.')
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Superuser must have is_superuser=True.')

        return self._create_user(username, email, password, **extra_fields)

Implementierung eines benutzerdefinierten Benutzermodells

Der Beamte empfiehlt die Implementierung eines benutzerdefinierten Benutzermodells. Befolgen Sie diese (. _.)

backend/src/common/models.py


from django.db import models
from django.contrib.auth.base_user import AbstractBaseUser
from django.contrib.auth.models import PermissionsMixin
from base.manager import UserManager
from base.models import BaseModel


class User(AbstractBaseUser, PermissionsMixin, BaseModel):
    email = models.EmailField('Mail Adresse', blank=True, null=True)
    username = models.CharField('Nutzername', max_length=150, unique=True)
    display_name = models.CharField('Anzeigename des Bildschirms', max_length=30, blank=True, null=True)
    last_name = models.CharField('Nachname', max_length=150, blank=True, null=True)
    first_name = models.CharField('Name', max_length=30, blank=True, null=True)
    is_staff = models.BooleanField('Mitarbeiterflagge', default=False)
    is_active = models.BooleanField('Gültiges Flag', default=True)
    first_login = models.BooleanField('Erster Login', default=True)

    objects = UserManager()

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

    class Meta:
        verbose_name = verbose_name_plural = 'users'
        db_table = 'user'

Ändern Sie settings.py

backend/src/config/settings/settings.py


.
..
...
AUTH_USER_MODEL = 'common.User'  #Geben Sie ein benutzerdefiniertes Benutzermodell für das zur Authentifizierung verwendete Benutzermodell an.

Wenn Sie vergessen, "AUTH_USER_MODEL" anzugeben, tritt der folgende Fehler auf.

python3 manage.py makemigrations
SystemCheckError: System check identified some issues:

ERRORS:
auth.User.groups: (fields.E304) Reverse accessor for 'User.groups' clashes with reverse accessor for 'User.groups'.
	HINT: Add or change a related_name argument to the definition for 'User.groups' or 'User.groups'.
auth.User.user_permissions: (fields.E304) Reverse accessor for 'User.user_permissions' clashes with reverse accessor for 'User.user_permissions'.
	HINT: Add or change a related_name argument to the definition for 'User.user_permissions' or 'User.user_permissions'.
common.User.groups: (fields.E304) Reverse accessor for 'User.groups' clashes with reverse accessor for 'User.groups'.
	HINT: Add or change a related_name argument to the definition for 'User.groups' or 'User.groups'.
common.User.user_permissions: (fields.E304) Reverse accessor for 'User.user_permissions' clashes with reverse accessor for 'User.user_permissions'.
	HINT: Add or change a related_name argument to the definition for 'User.user_permissions' or 'User.user_permissions'.

Migrationsdatei generieren

python3 manage.py makemigrations

Ausführung der Migration

python3 manage.py migrate

Recommended Posts

Tipps zum Django Rest Framework
Grundlagen des Django REST-Frameworks
Django REST Framework Stolperstein
Django REST Framework mit Vue.js
Melden Sie sich mit dem Django Rest Framework an
[Django] Verwenden Sie MessagePack mit dem Django REST-Framework
Tipps für Django-Vorlagen
Erstellen Sie eine RESTful-API mit dem Django Rest Framework
Verstehen Sie den Komfort des Django Rest Framework
Ein Verwaltungstool, das sofort mit dem REST-Framework ng-admin + Django erstellt werden kann
CRUD GET mit Nuxt & Django REST Framework ②
Verschiedene Hinweise zum Django REST-Framework
CRUD POST mit Nuxt & Django REST Framework
CRUD GET mit Nuxt & Django REST Framework ①
Überlegungen zum Design von Django REST Framework + Clean Architecture
Django Python Web Framework
CRUD PUT, DELETE mit Nuxt & Django REST Framework
Django REST Framework Ein wenig nützlich zu wissen.
Implementieren Sie die JWT-Anmeldefunktion im Django REST-Framework
Implementierung der Authentifizierungsfunktion in Django REST Framework mit djoser
Erstellen Sie eine Todo-App mit Django REST Framework + Angular
Weitere neue Benutzerauthentifizierungsmethoden mit Django REST Framework
Lassen Sie uns eine Todo-App mit dem Django REST-Framework erstellen
Erstellen Sie eine API für die Benutzerauthentifizierung mit Django REST Framework
Wenn Sie mit dem Django REST-Framework filtern möchten
Listenmethode für verschachtelte Ressourcen im Django REST-Framework
Implementieren Sie die API mit explosiver Geschwindigkeit mithilfe des Django REST Framework
Implementieren Sie hierarchische URLs mit drf-verschachtelten Routern im Django REST-Framework
So schreiben Sie eine benutzerdefinierte Validierung in Django REST Framework
Zurücksetzen des Passworts über die API mit dem Django Rest Framework
Django Rest Framework Dekorateure `Action Decorator ersetzt list_route und detail_route`
Implementierung von CRUD mithilfe der REST-API mit Python + Django Rest Framework + igGrid
Django
Installieren Sie das Python Framework Django mit pip
Erstellen Sie eine REST-API, um dynamodb mit dem Django REST Framework zu betreiben
Implementierung der benutzerdefinierten Authentifizierungsfunktion für Benutzermodelle in Django REST Framework mit djoser
Wie man mit verstümmelten Charakteren in json von Django REST Framework umgeht
Ich habe ein WebAPI gemacht! Erstellen einer Umgebung aus Django Rest Framework 1 mit EC2
Lösung, wenn nicht gefunden, wird angezeigt, wenn die API von Django REST Framework von außen aufgerufen wird
So generieren Sie automatisch ein API-Dokument mit dem Django REST-Framework und POST vom Dokumentbildschirm