Mir wurde von einer API mitgeteilt, die das Django-REST-Framework verwendet, das "eine Liste verschachtelter Ressourcen zurückgibt", und ich habe mich gegen "das Standarddesign der REST-API ist ..." ausgesprochen, aber ich habe es nicht getan, also habe ich es gemacht. Eine Notiz des Augenblicks.
Python 3.8.2 Django 3.0.5 djangorestframework 3.11.0
Parent ├ Child1 └ Child2 ↑ Bei einem Modell mit einer solchen Beziehung
models.py
from django.db import models
class Parent(models.Model):
"""
Übergeordnetes Modell
"""
parent_column = models.CharField(
max_length=10, verbose_name='Übergeordnete Modellspalte')
def __self__(self):
return self.parent_column
class Child1(models.Model):
"""
Kindermodell 1
"""
# related_Ordnen Sie den Namen dem Feldnamen des Serializers zu
parent = models.ForeignKey(Parent, on_delete=models.CASCADE, related_name='child1s')
child1_column = models.CharField(
max_length=10, verbose_name='Spalte des Kindermodells 1')
def __self__(self):
return self.Child1_column
class Child2(models.Model):
"""
Kindermodell 2
"""
# related_Ordnen Sie den Namen dem Feldnamen des Serializers zu
parent = models.ForeignKey(Parent, on_delete=models.CASCADE, related_name='child2s')
child2_column = models.CharField(
max_length=10, verbose_name='Spalte des Kindermodells 2')
def __self__(self):
return self.Child2_column
Mit der gleichen Konfiguration wie das Modell
models.py
from rest_framework import serializers
from .models import Parent, Child1, Child2
class Child1Serializer(serializers.ModelSerializer):
"""
Kinderserie1
"""
class Meta:
model = Child1
fields = [
'id',
'child1_column',
]
class Child2Serializer(serializers.ModelSerializer):
"""
Kinderserializer2
"""
class Meta:
model = Child2
fields = [
'id',
'child2_column',
]
class ParentSerializer(serializers.ModelSerializer):
"""
Übergeordneter Serializer
"""
#Definieren Sie einen untergeordneten Serializer als übergeordnetes Feld
#Dieser Feldname und das Modell beziehen sich_Übereinstimmungsname
child1s = Child1Serializer(many=True, read_only=True)
child2s = Child2Serializer(many=True, read_only=True)
class Meta:
model = Parent
fields = [
'id',
'parent_column',
'child1s',
'child2s',
]
Es scheint besser, QuerySet mit get_queryset () zu definieren, damit es später leicht durcheinander gebracht werden kann.
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):
"""
Listenmethode für verschachtelte Ressourcen
Ich möchte nur Liste verwenden, also Generika.Verwenden Sie ListAPIView
"""
pagination_class = PageNumberPagination
serializer_class = ParentSerializer
#Abfrage-konvertiert Parameter in Filter-Suchkriterien diktieren
CONDITION_KEYS = {
'parent_column': 'parent_column__contains',
'child1_column': 'child1s__child1_column__contains',
'child2_column': 'child2s__child2_column__contains',
}
def get_queryset(self):
"""
Möglicherweise schreiben Sie später ein kompliziertes QuerySet
Definieren Sie es an einem Ort, an den Sie gehen können.
"""
#Suchbedingung dikt
condition_dict = {}
for key, val in self.request.query_params.items():
# query_Wenn der Schlüssel von params ein Suchbedingungselement enthält, konvertieren Sie es in den Schlüssel für den Filter
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):
"""
Listenmethode überschreiben
"""
#Paginierung auf Queryset anwenden
page_qs = self.paginate_queryset(self.get_queryset())
#Holen Sie sich serialisieren
serializer = self.get_serializer(page_qs, many=True)
#Kehre mit Paginierung zurück
return self.get_paginated_response(serializer.data)
So was
Es war einfach.
https://github.com/ping2shi2/DRF-sample
Ich glaube, ich habe etwas anderes gesehen, aber ich habe vergessen ...
Recommended Posts