我们说我有以下型号......
class Product(models.Model):
name = models.CharField()
class Gift(models.Model):
product = models.ForeignKey(Product)
message = models.CharField()
......以下序列化程序......
class GiftSerializer(serializers.ModelSerializer):
product = ProductSerializer(read_only=True)
class Meta:
model = Gift
fields = ('product', 'message', )
...以及与' / gifts /'。
相关联的以下基于类的视图from rest_framework.generics import CreateListAPIView
class GiftList(CreateListAPIView):
queryset = Gift.objects.all()
serializer_class = GiftSerializer
如何使用关键产品'来创造礼物?代表这样的外键主键
self.client.post('/gifts/', {'product': 1, 'message': 'bar'})
但同时使用关键产品'
返回包含嵌套产品详情的信息self.client.get('/gifts/')
# {0: {"product": {"name": "foo"}, "message": "bar"}}
我通过将另一个只写的IntegerField添加到名为GiftSerializer
的{{1}}并覆盖product_pk
来实现我想要的目标:
to_internal_values
但问题是,如果验证失败,则使用字段def to_internal_value(self, data):
data['product_pk'] = data.pop('product')[0]
return super().to_internal_value(data)
而不是product_pk
返回异常,这是我希望的。
product
谢谢!
答案 0 :(得分:2)
另一种方法是创建两个序列化程序,
class GiftReadSerializer(serializers.ModelSerializer):
product = ProductSerializer(read_only=True)
class Meta:
model = Gift
fields = ('product', 'message', )
class GiftWriteSerializer(serializers.ModelSerializer):
class Meta:
model = Gift
fields = ('product', 'message', )
然后在基于类的视图中,您可以利用get_serializer_class
钩子:
from rest_framework.generics import CreateListAPIView
class GiftList(CreateListAPIView):
queryset = Gift.objects.all()
serializer_class = GiftSerializer
def get_serializer_class(self):
if self.request.method == ('POST' or 'PUT' or 'PATCH'):
return GiftWriteSerializer
else:
return GiftReadSerializer
答案 1 :(得分:0)
我设法通过覆盖to_internal_value
并动态修改字段来完成这项工作。
product_field = ProductSerializer()
pk_product_field = serializers.PrimaryKeyRelatedField(
queryset=Product.objects.all())
class GiftSerializer(object):
product = product_field
class Meta:
model = Gift
fields = ('product', 'message', )
def to_internal_value(self, data):
self.fields['product'] = pk_product_field
internal_value = super().to_internal_value(data)
self.fields['product'] = product_field
return internal_value