django rest framework:contenttype unique_together和serialization

时间:2016-08-25 01:17:45

标签: python django django-rest-framework

关于泛型关系的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 :(得分:0)

序列化验证在

中进行
def create(self, request, *args, **kwargs):

方法不在" perform_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或您想要的任何自定义响应。