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_idcontent_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框架基础

空视图上的Django rest框架错误:必须先呈现响应内容,然后才能对其进行迭代

无法让 CORS 与内容类型一起使用 - Django Rest Framework

Django rest 框架缓存策略

如何使用 django rest 框架和 angular 上传图片?

Django Rest 框架:支持任意 HTTP 动词的视图?