首页 文章

django rest framework:contenttype unique_together和serialization

提问于
浏览
0

关于泛型关系的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 回答

  • 0

    序列化器验证发生在

    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或任何自定义响应 .

相关问题