【问题标题】:django rest framework : contenttype unique_together and serializationdjango rest 框架:内容类型 unique_together 和序列化
【发布时间】: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 呢?

谢谢。

【问题讨论】:

    标签: python django django-rest-framework


    【解决方案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 属性中)
    猜你喜欢
    • 1970-01-01
    • 2018-06-24
    • 1970-01-01
    • 2013-03-31
    • 2016-04-07
    • 2012-11-16
    • 1970-01-01
    • 1970-01-01
    • 2016-06-22
    相关资源
    最近更新 更多