List, méthode pour les ressources imbriquées dans le framework Django REST

Une API qui utilise le framework Django REST m'a dit que "retourne une liste de ressources imbriquées", alors je me suis opposé à "la conception standard de l'API REST est ...", mais je ne l'ai pas fait, donc je l'ai fait. Une note du moment.

environnement

Python 3.8.2 Django 3.0.5 djangorestframework 3.11.0

modèle

Parent ├ Child1 └ Child2 ↑ Dans le cas d'un modèle avec une telle relation

models.py


from django.db import models

class Parent(models.Model):
    """
Modèle parent
    """
    parent_column = models.CharField(
        max_length=10, verbose_name='Colonne du modèle parent')

    def __self__(self):
        return self.parent_column

class Child1(models.Model):
    """
Modèle pour enfants 1
    """
    # related_Faire correspondre le nom avec le nom du champ du sérialiseur
    parent = models.ForeignKey(Parent, on_delete=models.CASCADE, related_name='child1s')
    child1_column = models.CharField(
        max_length=10, verbose_name='Colonne du modèle enfant 1')

    def __self__(self):
        return self.Child1_column

class Child2(models.Model):
    """
Modèle enfant 2
    """
    # related_Faire correspondre le nom avec le nom du champ du sérialiseur
    parent = models.ForeignKey(Parent, on_delete=models.CASCADE, related_name='child2s')
    child2_column = models.CharField(
        max_length=10, verbose_name='Colonne du modèle enfant 2')

    def __self__(self):
        return self.Child2_column

Sérialiseur

Avec la même configuration que le modèle

models.py


from rest_framework import serializers
from .models import Parent, Child1, Child2

class Child1Serializer(serializers.ModelSerializer):
    """
Sérialiseur pour enfants1
    """
    class Meta:
        model = Child1
        fields = [
            'id',
            'child1_column',
        ]

class Child2Serializer(serializers.ModelSerializer):
    """
Sérialiseur pour enfants2
    """
    class Meta:
        model = Child2
        fields = [
            'id',
            'child2_column',
        ]

class ParentSerializer(serializers.ModelSerializer):
    """
Sérialiseur parent
    """
    #Définir un sérialiseur enfant comme champ parent
    #Ce nom de champ et ce modèle sont liés_Match nom
    child1s = Child1Serializer(many=True, read_only=True)
    child2s = Child2Serializer(many=True, read_only=True)

    class Meta:
        model = Parent
        fields = [
            'id',
            'parent_column',
            'child1s',
            'child2s',
        ]

Vue

Il semble préférable de définir QuerySet avec get_queryset () afin qu'il puisse être facilement perturbé plus tard.

views.py


from rest_framework import generics
from rest_framework.pagination import PageNumberPagination

from .models import Parent
from .serializer import ParentSerializer

class NestedListView(generics.ListAPIView):
    """
Méthode de liste pour les ressources imbriquées
Je veux utiliser uniquement la liste, donc les génériques.Utiliser ListAPIView
    """
    pagination_class = PageNumberPagination
    serializer_class = ParentSerializer
    #Requête-convertit les paramètres en critères de recherche de filtre dict
    CONDITION_KEYS = {
        'parent_column': 'parent_column__contains',
        'child1_column': 'child1s__child1_column__contains',
        'child2_column': 'child2s__child2_column__contains',
        }

    def get_queryset(self):
        """
Vous pourriez finir par écrire un QuerySet compliqué plus tard, donc
Définissez-le dans un endroit où vous pouvez aller.
        """
        #Conditions de recherche dict
        condition_dict = {}
        for key, val in self.request.query_params.items():
            # query_S'il y a un élément de condition de recherche dans la clé des paramètres, convertissez-le en clé pour le filtre
            if key in self.CONDITION_KEYS:
                condition_dict[self.CONDITION_KEYS[key]] = val

        queryset = Parent.objects.filter(**condition_dict).order_by('id').prefetch_related().distinct()

        return queryset

    def list(self, request, *args, **kwargs):
        """
Méthode de liste de remplacement
        """
        #Appliquer la pagination à l'ensemble de requêtes
        page_qs = self.paginate_queryset(self.get_queryset())
        #Obtenez sérialiser
        serializer = self.get_serializer(page_qs, many=True)
        #Retour avec pagination
        return self.get_paginated_response(serializer.data)

Résultat d'exécution de l'API

Comme ça NestedListAPI.png

C'était facile.

La source

https://github.com/ping2shi2/DRF-sample

Les références

Je pense avoir vu autre chose, mais j'ai oublié ...

Recommended Posts

List, méthode pour les ressources imbriquées dans le framework Django REST
Suppression logique dans Django, DRF (Django REST Framework)
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
Bases du framework Django REST
Astuces Django Rest Framework
Notes d'apprentissage pour la fonction migrations dans le framework Django (3)
Notes d'apprentissage pour la fonction migrations dans le framework Django (1)
Implémenter des URL hiérarchiques avec des routeurs imbriqués drf dans le framework Django REST
Bloc d'achoppement du framework Django REST
Framework Django REST avec Vue.js
Connectez-vous avec Django Rest Framework
Comment écrire une validation personnalisée dans Django REST Framework
Liste des informations sur les arguments de méthode pour les classes et les modules en Python
Implémentation de la fonction d'authentification JWT dans Django REST Framework à l'aide de djoser
[Django] Utiliser MessagePack 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
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 ②
Changer la liste dans l'instruction for
Paramètre d'attribut de même site du cookie dans Django
CRUD POST avec Nuxt & Django REST Framework
Méthode de description pour réutiliser des variables dans shellscript
CRUD GET avec Nuxt & Django REST Framework ①
Obtenir les paramètres de requête pour les requêtes GET avec Django
Django REST Framework + Considération de conception d'architecture propre
Comment vous permettre d'essayer les fonctionnalités du framework django rest dans un seul fichier
CRUD PUT, DELETE avec Nuxt & Django REST Framework
Framework Django REST Un peu utile à savoir.
Comment créer une API Rest dans Django
Faites une recherche ambiguë pour mysql dans Django