Betrachten Sie den Fall eines Modells mit einer rekursiven Beziehung (z. B. einer Baumstruktur). Erstellen Sie mit dem Django REST Framework eine API, die json rekursiv zurückgibt.
MacOS(10.11.6 / ElCapitane) Python 3.5.2 Django 1.10.4 DjangoRESTFramework 3.5.3
Model
Definiert ein Modell mit einer rekursiven Beziehung. Stellen Sie sich ein Modell vor, das mehr Unterkategorien innerhalb der Kategorie enthält. Der Name der umgekehrten Beziehung lautet Unterkategorien.
models.py
class Category(models.Model):
parentCategory = models.ForeignKey('self', blank=True, null=True, related_name='subcategories')
name = models.CharField(max_length=200)
description = models.CharField(max_length=500)
Serializer Definieren Sie einen SubCategorySerializer, der den ModelSerializer erbt, und überschreiben Sie die Unterkategorien, die die umgekehrten Beziehungen der Kategorie darstellen, mit dem SubCategorySerializer. Zu diesem Zeitpunkt sollte parentCategory serializers.PrimaryKeyRelatedField () zurückgeben.
serializers.py
class SubCategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = ('name', 'description')
class CategorySerializer(serializers.ModelSerializer):
parentCategory = serializers.PrimaryKeyRelatedField()
subcategories = serializers.SubCategorySerializer()
class Meta:
model = Category
fields = ('parentCategory', 'name', 'description', 'subcategories')
View
Es ist in Ordnung, wenn Sie CategorySerializer für Serializer in View angeben. Der Abfragesatz sollte eine Abfrage sein, mit der die oberste Hierarchie eindeutig abgerufen werden kann. Wenn Sie get () verwenden, erhalten Sie das Objekt. Verwenden Sie daher filter (), das eine Abfrage zurückgibt. (Definieren Sie beispielsweise is_root im Modell und rufen Sie es mit filter ab (is_root = True).)
view.py
class CategoryListViewSet(viewsets.ModelViewSet):
queryset = Category.objects.filter(id='e.g...root_category_id').prefetch_related('subcategories__subcategories')
serializer_class = CategorySeriarizer
Dies kann auch durch Definieren und Zurückgeben des folgenden rekursiven Felds realisiert werden. Ich finde das auch gut, weil es flexibel ist.
serializers.py
class RecursiveField(serializers.Serializer):
def to_representation(self, value):
serializer = self.parent.parent.__class__(value, context=self.context)
return serializer.data
class CategorySerializer(serializers.Serializer):
subcategories = RecursiveField(many=True)
class Meta:
model = Comment
fields = ('parendCategory','name', 'description', 'subcategories')
Es ist ein anderes Modell als im obigen Beispiel, aber wenn es sich um ein Dateisystemmodell mit einer einfachen Baumstruktur und rekursiven Beziehungen handelt, wird dieser JSON zurückgegeben.
hoge.json
[
{
"name": "RootDirectory",
"is_root": true,
"is_dir": true,
"parent_file": null,
"child_files": [
{
"name": "root_file",
"is_root": false,
"is_dir": false,
"parent_file": 34,
"child_files": []
},
{
"name": "TestDir",
"is_root": false,
"is_dir": true,
"parent_file": 34,
"child_files": [
{
"name": "test.zip",
"is_root": false,
"is_dir": false,
"parent_file": 35,
"child_files": []
},
{
"name": "test_dir_file.png ",
"is_root": false,
"is_dir": false,
"parent_file": 35,
"child_files": []
}
]
}
]
}
]
Lasst uns alle Spaß mit Django haben und eine REST-API erstellen! !!
http://www.django-rest-framework.org/api-guide/relations/#custom-relational-fields http://stackoverflow.com/questions/13376894/django-rest-framework-nested-self-referential-objects