我对django rest框架有一个关于泛型关系的小问题,这个泛型关系也用于唯一的约束。
我有这个模型:
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'))
它有一个通用关系和一个唯一的约束:专有网络的名称和通用关系(即所有者)。
以下是序列化程序:
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,因为我不想让用户显示/设置它们。
但是,我必须把它们放在UniqueTobetherValidator中,以避免在创建具有相同帐户/名称的VPC时出现django.db.utils.integrityerror的错误。
但现在,当我尝试创建VPC时,出现了以下错误:
{"object_id":["此字段是必需的。"],"content_type":["此字段是必需的。"]}
所以在我的视图集中。ModelViewSet我试图重写perform_create()以设置对象id和内容类型,但似乎在调用此方法之前引发了错误。
我还尝试重写get_serializer_context(),以返回包含对象id和内容类型的字典,但这两种方法都不起作用。
我花了很多时间在这上面,但我没有发现。那么,我应该重写什么方法才能在序列化器中设置object_id和content_type呢?
谢谢
序列化程序验证在
def create(self, request, *args, **kwargs):
方法不在“执行创建”中
您需要覆盖“创建”方法,并在请求数据中填充“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或任何所需的自定义响应。