Ich verwende das Django Rest Framework, um eine API zu erstellen. Ich habe folgende Modelle:
class Category(models.Model):
name = models.CharField(max_length=100)
def __unicode__(self):
return self.name
class Item(models.Model):
name = models.CharField(max_length=100)
category = models.ForeignKey(Category, related_name='items')
def __unicode__(self):
return self.name
So erstellen Sie einen Serializer für die Kategorien:
class CategorySerializer(serializers.ModelSerializer):
items = serializers.RelatedField(many=True)
class Meta:
model = Category
... und das würde mich versorgen mit:
[{'items': [u'Item 1', u'Item 2', u'Item 3'], u'id': 1, 'name': u'Cat 1'},
{'items': [u'Item 4', u'Item 5', u'Item 6'], u'id': 2, 'name': u'Cat 2'},
{'items': [u'Item 7', u'Item 8', u'Item 9'], u'id': 3, 'name': u'Cat 3'}]
Wie würde ich vorgehen, um das Gegenteil von einem Item-Serializer zu erhalten, dh:
[{u'id': 1, 'name': 'Item 1', 'category_name': u'Cat 1'},
{u'id': 2, 'name': 'Item 2', 'category_name': u'Cat 1'},
{u'id': 3, 'name': 'Item 3', 'category_name': u'Cat 1'},
{u'id': 4, 'name': 'Item 4', 'category_name': u'Cat 2'},
{u'id': 5, 'name': 'Item 5', 'category_name': u'Cat 2'},
{u'id': 6, 'name': 'Item 6', 'category_name': u'Cat 2'},
{u'id': 7, 'name': 'Item 7', 'category_name': u'Cat 3'},
{u'id': 8, 'name': 'Item 8', 'category_name': u'Cat 3'},
{u'id': 9, 'name': 'Item 9', 'category_name': u'Cat 3'}]
Ich habe die Dokumente zu umgekehrten Beziehungen für das Rest-Framework gelesen, aber das scheint das gleiche Ergebnis zu sein wie die nicht umgekehrten Felder. Vermisse ich etwas Offensichtliches?
quelle
Relational field must provide a 'queryset' argument, or set read_only='True'
category_name = serializers.RelatedField(source='category', queryset=Category.objects.all())
Ich nehme an.AssertionError:...
verwenden Sie diese Antwort stackoverflow.com/a/44530606/5403449In der DRF-Version 3.6.3 hat dies bei mir funktioniert
class ItemSerializer(serializers.ModelSerializer): category_name = serializers.CharField(source='category.name') class Meta: model = Item fields = ('id', 'name', 'category_name')
Weitere Informationen finden Sie hier: Kernargumente der Serializer-Felder
quelle
Sie können auch Folgendes tun:
Item
Modell eine Eigenschaft , die den Kategorienamen und zurückgibtReadOnlyField
.Ihr Modell würde so aussehen.
class Item(models.Model): name = models.CharField(max_length=100) category = models.ForeignKey(Category, related_name='items') def __unicode__(self): return self.name @property def category_name(self): return self.category.name
Ihr Serializer würde so aussehen. Beachten Sie, dass der Serializer automatisch den Wert der
category_name
Modelleigenschaft erhält, indem er das Feld mit demselben Namen benennt.class ItemSerializer(serializers.ModelSerializer): category_name = serializers.ReadOnlyField() class Meta: model = Item
quelle
das hat bei mir gut funktioniert:
class ItemSerializer(serializers.ModelSerializer): category_name = serializers.ReadOnlyField(source='category.name') class Meta: model = Item fields = "__all__"
quelle
Arbeitete am 08/08/2018 und an der DRF-Version 3.8.2:
class ItemSerializer(serializers.ModelSerializer): category_name = serializers.ReadOnlyField(source='category.name') class Meta: model = Item read_only_fields = ('id', 'category_name') fields = ('id', 'category_name', 'name',)
Mit dem Meta können
read_only_fields
wir genau deklarieren, welche Felder read_only sein sollen. Dann müssen wir dasforeign
Feld auf der Meta deklarierenfields
(besser explizit sein, wie das Mantra sagt: Zen of Python ).quelle
Einfache Lösung,
source='category.name'
bei dercategory
es sich um einen Fremdschlüssel und.name
dessen Attribut handelt.from rest_framework.serializers import ModelSerializer, ReadOnlyField from my_app.models import Item class ItemSerializer(ModelSerializer): category_name = ReadOnlyField(source='category.name') class Meta: model = Item fields = "__all__"
quelle
Diese Lösung ist besser, da das Quellmodell nicht definiert werden muss. Der Name des Serializer-Felds sollte jedoch mit dem Namen des Fremdschlüsselfelds übereinstimmen
class ItemSerializer(serializers.ModelSerializer): category = serializers.SlugRelatedField(read_only=True, slug_field='title') class Meta: model = Item fields = ('id', 'name', 'category')
quelle