[PYTHON] Astuces Django Rest Framework

information sur la version

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

Je veux utiliser Swagger

Installez django-rest-swagger avec pip

pip3 install django-rest-swagger==2.2.0

Modifier 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',
    )
}

Développement fixe.py

backend/src/config/settings/developement.py


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

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

Correction de urls.py

backend/src/config/urls.py


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

urlpatterns = [
    path('admin/', admin.site.urls),
    url('api/v1/login/', obtain_jwt_token),  #Swagger sans une ou plusieurs API-Il semble que l'interface utilisateur ne puisse pas être ouverte, alors enregistrez l'API de connexion pour le moment
]

#Tout ajouter ci-dessous
if settings.DEBUG:  # DEBUG=Utilisé uniquement lorsque True (pendant le développement)
    from rest_framework.schemas import get_schema_view
    from rest_framework_swagger import renderers
    schema_view = get_schema_view(
        title='Liste des API',
        public=True,
        renderer_classes=[renderers.OpenAPIRenderer, renderers.SwaggerUIRenderer])
    urlpatterns += [
        url(API_ROOT + 'api-auth/', include('rest_framework.urls')),
        url('swagger-ui/', schema_view),
    ]

Accéder à Swagger-ui

Accédez à http://0.0.0.0:8000/swagger-ui/ et lorsque l'écran suivant apparaît, Log in en haut à droite Appuyez pour vous connecter image.png

image.png

image.png

Voir les ensembles

Je souhaite publier l'API de GET, POST, PUT, DELETE ... pour le modèle pour le moment

Vous pouvez utiliser les ModelViewSets que tout le monde aime.

backend/src/api/users/views.py


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


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

Terminé (en utilisant swagger-ui) image.png

Je souhaite affiner les méthodes de requête HTTP à publier

Méthode 1: Combinez GenericViewSet avec divers mixins

Si vous souhaitez augmenter le nombre de méthodes de requête ultérieurement, ajoutez les mixins correspondants.

backend/src/api/users/views.py


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


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

image.png

Méthode 2: utiliser des génériques

Si vous souhaitez augmenter le nombre de méthodes de requête ultérieurement, vous pouvez ajouter l'APIView correspondant.

backend/src/api/users/views.py


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


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

Pour les génériques, la méthode de spécification de urls.py est différente

backend/src/config/urls.py


# =========== viewsets ===========
router = DefaultRouter()
router.register('user', user_views.UserViewSets)  #Dans le cas des vues, le routeur peut être utilisé

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()),  #quant aux modèles d'URL_views()Ajouter avec
]

Le résultat est le même que la méthode 1 image.png

Je souhaite utiliser ModelViewSet, mais je souhaite affiner la méthode de requête HTTP (voir)

Pour une personne aussi égoïste, c'est http_method_names. Je me demande s'il sera utilisé dans des situations où je l'ai implémenté mais que je ne souhaite pas encore le publier.

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']  #La méthode de requête HTTP est en minuscule (important), pas en majuscule

image.png

Je souhaite limiter les demandes d'API aux utilisateurs authentifiés uniquement

Spécifions ʻIsAuthenticated` pour permission_class.

Tout d'abord, modifiez settings.py.

backend/src/config/settings/settings.py


.
..
...
REST_FRAMEWORK = {
    #ajouter à
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
        # 'common.permissions.IsSuperuser',  #Si vous avez créé votre propre autorisation, ajoutez-la ici.
    ),
    ...
    ..
    .
}

Si vous demandez l'API dans l'état non authentifié, «403» sera renvoyé.

backend/src/api/users/views.py


from api.users.serializers import UserSerializer
from common.models import User
from rest_framework.permissions import IsAuthenticated  #ajouter à
from rest_framework.viewsets import ModelViewSet


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

Je souhaite ajouter une méthode ad hoc routable (detail = False)

Dans un tel cas, c'est un décorateur «@ action». (Si la version DRF est ancienne, il s'agit du décorateur @ list_route ou @ detail_route. Il semble qu'il ait été intégré dans le décorateur @ action.)

backend/src/api/users/views.py


from api.users.serializers import UserSerializer
from common.models import User
from rest_framework.decorators import action  #ajouter à
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):
        """Renvoie les informations de connexion de l'utilisateur
        """
        return UserSerializer(self.request.user).data

image.png

Je souhaite ajouter une méthode ad hoc routable (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):
        """Renvoie les informations de connexion de l'utilisateur
        """
        #Le processus est defail=Identique à False. Je suis désolé(. _ .)
        return Response(
            status=status.HTTP_200_OK,
            data=UserSerializer(self.request.user).data)

Ce sera une API telle que ʻapi_root / {pk} / url_name / `. image.png

Je souhaite ajouter une méthode ad hoc routable. Je veux inclure la clé primaire dans l'URL, mais False est bon pour le détail du décorateur @action (voir)

Une personne aussi égoïste est le décorateur «@ action» «chemin_url».

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):
        """Renvoie les informations de connexion de l'utilisateur
        """
        return Response(
            status=status.HTTP_200_OK,
            data=UserSerializer(self.request.user).data)

Il peut être recommandé pour ceux qui n'aiment pas l'URL générée par detail = True lol

image.png

Je veux pouvoir rechercher par paramètres de requête

Installer django-filter avec pip

pip3 install django-filter==2.2.0

Créez filters.py (le nom du fichier est arbitraire) et définissez des filtres

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__'

        #Les champs que vous ne souhaitez pas spécifier dans le paramètre de requête doivent être ajoutés pour être exclus.
        # exclude = [
        #     'password',
        #     'date_created',
        #     'date_updated',
        # ]

Utiliser le filtre défini dans les vues

backend/src/api/users/views.py


from api.users.serializers import UserSerializer
from common.models import User
from django_filters.rest_framework import DjangoFilterBackend  #ajouter à
from api.users.filters import UserSearchFilter  #ajouter à
from rest_framework.viewsets import ModelViewSet


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

Vous pourrez GET en spécifiant les paramètres de requête.

image.png

Édition Serializer

Tout le monde aime Model Serializer

backend/src/api/users/serializers.py


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


class UserSerializer(ModelSerializer):
    """Sérialiseur utilisateur
    """
    class Meta:
        model = User
        fields = '__all__'

Je veux affiner les paramètres

Je ne veux pas lancer de groupes ou de user_permissions comme paramètres

image.png

Dans un tel cas, spécifiez ʻextra_kwargs`.

backend/src/api/users/serializers.py


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


class UserSerializer(ModelSerializer):
    """Sérialiseur utilisateur
    """
    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},
        }

Je l'ai pressé en toute sécurité ↓ image.png

Comme il est uniquement en lecture seule (lecture seule), il inclura celui spécifié dans ʻextra_kwargs` au moment de l'acquisition (GET). image.png

Je souhaite renvoyer le résultat d'une fonction / méthode en tant que valeur de champ

Par exemple, la valeur de la destination de la relation contient uniquement la clé primaire.

Dans un tel cas, vous pouvez utiliser SerializerMethodField. Après avoir défini les champs, nous préparerons une fonction pour get_field name.

backend/src/api/users/serializers.py


import json  #ajouter à
from django.core.serializers import serialize  #ajouter à
from rest_framework.serializers import ModelSerializer, SerializerMethodField  #ajouter à
from common.models import User


class UserSerializer(ModelSerializer):
    """Sérialiseur utilisateur
    """
    school = SerializerMethodField()  #Ajouter le champ

    # get_Ajout d'une fonction pour le nom du champ
    def get_school(self, obj):
        """Renvoie un objet sérialisé JSON de l'objet école

        Args:
            obj (User):Objet utilisateur
        
        Returns:
            dict:Un objet qui sérialise l'objet User au format JSON
        """
        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:
        ...

L'objet école a été étendu à école, qui était la clé principale auparavant (. _.) SerializerMethodField est pratique car il peut renvoyer n'importe quelle valeur ensemble.

image.png

Je veux renvoyer l'objet auquel je suis lié. Mais je ne comprends pas SerializerMethodField (Teru)

Un tel égoïsme est une option de «profondeur».

backend/src/api/users/serializers.py


from common.models import User


class UserSerializer(ModelSerializer):
    """Sérialiseur utilisateur
    """
    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  #La valeur par défaut est 0, il est donc inutile de spécifier 0

image.png

Si vous faites depth = 2, cela obtiendra encore plus de relations. (Dans cet exemple, si l'école a plus de relations à venir, elle renverra également cet objet)

édition djangorestframework-jwt

Je souhaite inclure des informations utilisateur en plus du jeton dans la réponse de gets_jwt_token

Par défaut, il ne renvoie que «token». image.png

Si vous souhaitez inclure ici les informations utilisateur en plus du jeton, créez votre propre jwt_response_payload_handler. Créez jwt_utils.py (le nom du fichier est arbitraire)

backend/src/common/jwt_utils.py


def jwt_response_payload_handler(token, user=None, request=None):
    """Réponse personnalisée pour l'authentification JWT
    """
    return {
        'token': token,
        'first_login': user.first_login,
        'id': user.id,
    }

Modifiez settings.py.

backend/src/config/settings/settings.py


.
..
...
# JWT_Ajouter AUTH
JWT_AUTH = {
    'JWT_RESPONSE_PAYLOAD_HANDLER': 'common.jwt_utils.jwt_response_payload_handler',  # JWT_RESPONSE_PAYLOAD_Jwt fait maison pour MANIPULATEUR_response_payload_Spécifier le gestionnaire
}

J'ai pu augmenter la réponse (. _.)

image.png

Introduction à Django Project, Django Rest Framework

pip installer django-environ, Django et le framework djangorest

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

Créer le répertoire src racine et backend du projet

mkdir -p project_root/backend/src

La structure des répertoires est la suivante

project_root #Racine du projet
└── backend
    └── src

Création de projet Django

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

La structure des répertoires est la suivante (les fichiers de configuration peuvent être collectés dans config)

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

Divisez le fichier de configuration en développement et production

project_root #Racine du projet
└── backend
     └── src
         ├── config
         │    ├── __init__.py
         │    ├── settings
         │    │    ├── settings.py
         │    │    ├── development.py  #Pour le developpement
         │    │    └── production.py  #Pour la production
         │    │
         │    ├── urls.py
         │    └── wsgi.py
         └── manage.py

Correction due au réglage de la division des fichiers

Modifier settings.py (Correction de BASE_DIR pour être le répertoire src)

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
...
..
.

Correction de manage.py

backend/src/manage.py


.
..
...
def main():
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'confing.settings')
     │
     ↓
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'confing.settings.development')  #Lire le développement
...
..
.

Modifiez wsgi.py pour le déploiement

backend/src/config/wsgi.py


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

Développement fixe.py

backend/src/config/settings/development.py


from confing.settings.settings import *

ALLOWED_HOSTS = ['*']

Modifier production.py

backend/src/config/settings/development.py


from confing.settings.settings import *

Rendre DRF disponible

Modifier 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',  #Postscript
]

Lancer des conteneurs Web et db avec Docker

Préparez docker-compose.yml et Dockerfile

project_root #Racine du projet
├── backend
│    ├── src
│    │   ├── config
│    │   │    ├── __init__.py
│    │   │    ├── settings
│    │   │    │    ├── settings.py
│    │   │    │    ├── development.py
│    │   │    │    └── production.py
│    │   │    │
│    │   │    ├── urls.py
│    │   │    └── wsgi.py
│    │   |
│    │   └── manage.py
│    │
│    └── Dockerfile  #ajouter à
│
└── docker-compose.yml  #ajouter à

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

Démarrer le conteneur Docker

docker-compose up -d

Visitez la page de démarrage de Django

Succès si cet écran apparaît image.png

Créer un fichier .env.development

cd backend/src/
touch .env.development

Contenu du fichier .env.development

backend/src/.env.development


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

Développement fixe.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()  #Lire les informations de connexion à la base de données (.env.BASE DE DONNÉES de développement_Lira l'URL)
...
..
.

Implémentation du modèle de base

Créer une application de base

django-admin startapp base

Ajouté à INSTALLED_APPS dans settings.py

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

Décrire 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):
    """Modèle de base
    """
    date_created = models.DateTimeField('Date et heure de création', default=timezone.now)
    date_updated = models.DateTimeField('Dernière modification', auto_now_add=True)
    date_deleted = models.DateTimeField('Supprimer la date et l'heure', null=True)

    class Meta:
        abstract = True  #← Obligatoire

Implémentation d'un modèle utilisateur personnalisé

Créer une application commune

django-admin startapp common

Ajouté à INSTALLED_APPS dans settings.py

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

Premier gestionnaire d'utilisateurs d'implémentation

Créer 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)

Implémentation de modèle utilisateur personnalisé

Le fonctionnaire recommande de mettre en œuvre un modèle d'utilisateur personnalisé, alors suivez-le (. _.)

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('adresse mail', blank=True, null=True)
    username = models.CharField('Nom d'utilisateur', max_length=150, unique=True)
    display_name = models.CharField('Nom d'affichage de l'écran', max_length=30, blank=True, null=True)
    last_name = models.CharField('Nom de famille', max_length=150, blank=True, null=True)
    first_name = models.CharField('Nom', max_length=30, blank=True, null=True)
    is_staff = models.BooleanField('Drapeau du personnel', default=False)
    is_active = models.BooleanField('Drapeau valide', default=True)
    first_login = models.BooleanField('Première connexion', default=True)

    objects = UserManager()

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

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

Modifier settings.py

backend/src/config/settings/settings.py


.
..
...
AUTH_USER_MODEL = 'common.User'  #Spécifiez un modèle utilisateur personnalisé pour le modèle utilisateur utilisé pour l'authentification.

Si vous oubliez de spécifier ʻAUTH_USER_MODEL`, vous souffrirez de l'erreur suivante.

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'.

Générer le fichier de migration

python3 manage.py makemigrations

Exécution de la migration

python3 manage.py migrate

Recommended Posts

Astuces Django Rest Framework
Bases du framework Django REST
Bloc d'achoppement du framework Django REST
Framework Django REST avec Vue.js
Connectez-vous avec Django Rest Framework
[Django] Utiliser MessagePack avec le framework Django REST
Astuces pour les modèles Django
Créer une API RESTful avec Django Rest Framework
Comprendre la commodité de Django Rest Framework
Un outil administratif qui peut être créé immédiatement avec le framework ng-admin + Django REST
CRUD GET avec Nuxt & Django REST Framework ②
Notes diverses sur le framework Django REST
CRUD POST avec Nuxt & Django REST Framework
CRUD GET avec Nuxt & Django REST Framework ①
Django REST Framework + Considération de conception d'architecture propre
Framework Web Django Python
CRUD PUT, DELETE avec Nuxt & Django REST Framework
Framework Django REST Un peu utile à savoir.
Implémenter la fonctionnalité de connexion JWT dans le framework Django REST
Implémentation de la fonction d'authentification dans Django REST Framework à l'aide de djoser
Créer une application Todo avec Django REST Framework + Angular
Plus de nouvelles méthodes d'authentification des utilisateurs avec Django REST Framework
Essayez de créer une application Todo avec le framework Django REST
Créer une API autour de l'authentification des utilisateurs avec Django REST Framework
Lorsque vous souhaitez filtrer avec le framework Django REST
List, méthode pour les ressources imbriquées dans le framework Django REST
Implémentez l'API à une vitesse explosive en utilisant Django REST Framework
Implémenter des URL hiérarchiques avec des routeurs imbriqués drf dans le framework Django REST
Comment écrire une validation personnalisée dans Django REST Framework
Comment réinitialiser le mot de passe via l'API à l'aide du framework Rest Django
Décorateurs du cadre de repos Django ʻaction decorator remplace list_route et detail_route`
Implémentation de CRUD à l'aide de l'API REST avec Python + Django Rest framework + igGrid
Django
Installer le framework Python django à l'aide de pip
Créer une API REST pour faire fonctionner dynamodb avec le Framework Django REST
Implémentation de la fonction d'authentification du modèle utilisateur personnalisé dans Django REST Framework à l'aide de djoser
Comment gérer les caractères déformés dans json de Django REST Framework
J'ai fait une webAPI! Construire un environnement à partir de Django Rest Framework 1 avec EC2
Solution lorsque Not Found apparaît lors de la frappe de l'API de Django REST Framework de l'extérieur
Comment générer automatiquement un document API avec le framework Django REST et POST à partir de l'écran de document