我正在尝试使用Django Rest Framework 3.0构建嵌套关系。我已经创建了序列化程序并试图覆盖create()
函数。我的模型定义如下:
class Item(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL)
name = models.CharField(max_length=200)
description = models.CharField(max_length=1000)
categories = models.ManyToManyField(Category, null=True, blank=True)
class Price(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL)
item = models.ForeignKey(Item, related_name='prices')
name = models.CharField(max_length=100)
cost = models.FloatField()
正如您所知,我的商品可以有多种价格。我的序列化器定义如下:
class PriceSerializer(serializers.ModelSerializer):
class Meta:
model = Price
owner = serializers.Field(source='owner.username')
exclude = ('user',)
class ItemSerializer(serializers.ModelSerializer):
prices = PriceSerializer(many=True, required=False)
categories = CategorySerializer(many=True, required=False)
class Meta:
model = Item
owner = serializers.Field(source='owner.username')
fields = ('id', 'name', 'description', 'prices', 'categories')
def create(self, validated_data):
user = validated_data.get('user')
# Get our categories
category_data = validated_data.pop('categories')
# Create our item
item = Item.objects.create(**validated_data)
# Process the categories. We create any new categories, or return the ID of existing
# categories.
for category in category_data:
category['name'] = category['name'].title()
category, created = Category.objects.get_or_create(user=user, **category)
item.categories.add(category.id)
item.save()
return item
当我尝试发布新项目时:
{
"name": "Testing",
"description": "This is a test",
"categories": [
{
"name": "foo"
},
{
"name": "bar"
}
],
"prices": [
{
"name": "Red",
"cost": 10
}
]
}
我收到以下错误:
{
"prices": [
{
"item": [
"This field is required."
]
}
]
}
大概是因为价格序列化器不知道新商品的ID是什么。我已尝试在我的序列化程序的create()
函数中覆盖此功能,但在我有机会创建项目并将其与价格相关联之前,好像序列化程序的验证正在被点击。
那么 - 如何创建新项目,获取项目ID,然后创建每个新价格?
答案 0 :(得分:5)
问题是您的PriceSerializer
正在寻找item
密钥,因为它是在Price
模型上指定的。这并不是很明显,因为您使用的是Meta.exclude
而不是Meta.fields
。
class PriceSerializer(serializers.ModelSerializer):
class Meta:
model = Price
exclude = ('user',)
与写作相同
class PriceSerializer(serializers.ModelSerializer):
class Meta:
model = Price
fields = ('id', 'item', 'name', 'cost', )
这使得您的问题非常清楚。由于模型上的item
字段未设置empty=True
(或null=True
),因此Django REST Framework会自动generates it as a PrimaryKeyRelatedField
required=True
。这就是为什么你得到This field is required
必需的错误,因为Django REST Framework无法自动检测到它来自已经拥有该字段的父序列化程序。
您可以通过从序列化程序中删除字段来解决此问题,因为它似乎不需要。
class PriceSerializer(serializers.ModelSerializer):
class Meta:
model = Price
fields = ('id', 'name', 'cost', )
这将不再显示item
字段,但我怀疑这对您来说实际上不是问题。