django rest 框架:内容类型 unique_together 和序列化
Posted
技术标签:
【中文标题】django rest 框架:内容类型 unique_together 和序列化【英文标题】:django rest framework : contenttype unique_together and serialization 【发布时间】:2016-08-25 01:17:45 【问题描述】:我对 django rest 框架有一点关于泛型关系的问题,该泛型关系也用于 unique_together 约束。
我有这个模型:
class VPC(models.Model):
name = models.SlugField(null=False, max_length=100)
deletable = models.BooleanField(null=False, default=True)
date_created = models.DateTimeField(auto_now_add=True)
date_modified = models.DateTimeField(auto_now=True)
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
class Meta:
unique_together = (('name', 'content_type', 'object_id'))
它具有通用关系和唯一约束:vpc 的名称 + 通用关系(即所有者)。
这是序列化程序:
class VPCSerializer(serializers.ModelSerializer):
class Meta:
model = VPC
read_only_fields = ('deletable', 'date_created', 'date_modified')
fields = ('name', 'deletable')
lookup_field = 'name'
validators = [
UniqueTogetherValidator(
queryset=VPC.objects.all(),
fields=('name', 'content_type', 'object_id')
)
]
在字段中我没有放置 content_type 和 object_id,因为我不希望它们被用户显示/设置。
但我必须将它们放在 UniqueTogetherValidator 中,以避免在创建具有相同帐户/名称的 VPC 时出现 django.db.utils.integrityerror 引发的错误。
但现在当我尝试创建 VPC 时出现此错误:
"object_id":["此字段为必填项。"],"content_type":["此字段为必填项。"]
所以在我的 viewsets.ModelViewSet 我试图覆盖 perform_create() 设置 object_id 和 content_type 但看起来在调用此方法之前引发了错误。
我也尝试重写 get_serializer_context() 以返回包含 object_id 和 content_type 的字典,但它也不起作用。
我花了很多时间在这上面,但我没有发现。 那么我应该重写什么方法才能在序列化程序中设置 object_id 和 content_type 呢?
谢谢。
【问题讨论】:
【参考方案1】:序列化验证发生在
def create(self, request, *args, **kwargs):
方法不在“perform_create”中
您需要重写“create”方法并将“content_type”、“object_id”填充到请求数据(将用于初始化序列化程序和验证)。
你可以这样做,例如,
def create(self, request, *args, **kwargs):
if hasattr(request.data, '_mutable'):
request.data._mutable = True
request.data['content_type'] = "your_content_type"
request.data['content_type'] = "your_object_id"
serializer = VPCSerializer(data=request.data, request=request)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
return Response here..
只需在初始化序列化程序并检查验证之前填写所需的数据,然后使用序列化程序对象保存并返回serilizer.data 或您想要的任何自定义响应。
【讨论】:
非常感谢,它有效! (注意:将 content_type 和 object_id 添加到序列化程序的 fields 属性中)以上是关于django rest 框架:内容类型 unique_together 和序列化的主要内容,如果未能解决你的问题,请参考以下文章
空视图上的Django rest框架错误:必须先呈现响应内容,然后才能对其进行迭代
无法让 CORS 与内容类型一起使用 - Django Rest Framework