在Django REST框架中禁止"字段应该是唯一的"错误

The*_*her 9 python django serialization django-rest-framework

我有一个像这样的模特

class MyModel(models.Model):
    uuid = models.CharField(max_length=40, unique=True)
Run Code Online (Sandbox Code Playgroud)

和一个序列化器

class MyModelSerializer(serializers.ModelSerializer):    
    class Meta:
         model = MyModel
    fields = ('uuid')
Run Code Online (Sandbox Code Playgroud)

我希望通过MyModel对象接收JSON,但它可以是现有对象.因此,当我使用serializer.is_valid()有关现有对象的数据时,它会给我一个错误:

for record in request['records']: 
    # request - body of JSON request, 
    # 'records' - array of records I want to add or update

    serializer = MyModelSerializer(data=record)
    if serializer.is_valid():
        # Do stuff
        serializer.save()
Run Code Online (Sandbox Code Playgroud)

错误:

 {"uuid":["This field must be unique."]}
Run Code Online (Sandbox Code Playgroud)

有没有办法分离新对象和现有对象的行为?特别是,我想创建新MyModel对象,如果它不是数据库,并更新现有MyModel对象(如果它存在).

Fiv*_*ver 5

通过尝试使用 POST 请求创建新实例和更新现有实例,您基本上是在重载 REST API 的单个入口点。此外,您似乎正在尝试在单个POST 请求中同时创建和更新多个实例。

Django REST Framework (DRF) 期望 POST 请求仅创建新实例。因此,发送现有实例记录会触发该uuid字段的唯一约束违规,因为 DRF 尝试将该记录创建为新实例,因为现有实例已经具有该 uuid 值。

使您的 REST API 更加“RESTful”的解决方案是将记录的创建和更新分别分离为 POST 和 PUT 请求。不清楚您是否使用DRF 提供通用 API 视图,但您可以使用CreateAPIViewPOST 新实例,然后创建一个单独UpdateAPIView的 PUT 和/或 PATCH 现有实例。更好的是,您可以使用通用视图ListCreateAPIViewRetrieveUpdateAPIView.

最后,为了处理批量请求(即单个请求中的多个实例),您可以覆盖内置视图方法或使用django-rest-framework-bulk 等第3 方包。