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

时间:2015-03-25 05:01:11

标签: python django serialization django-rest-framework

我有一个类似

的模型
class MyModel(models.Model):
    uuid = models.CharField(max_length=40, unique=True)

和序列化程序

class MyModelSerializer(serializers.ModelSerializer):    
    class Meta:
         model = MyModel
    fields = ('uuid')

我希望通过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()

错误:

 {"uuid":["This field must be unique."]}

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

2 个答案:

答案 0 :(得分:3)

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

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

使REST API更“RESTful”的解决方案是分别将记录的创建和更新分为POST和PUT请求。目前还不清楚您是否使用generic API views provided by DRF,但可以使用CreateAPIView POST新实例,然后创建单独的UpdateAPIView到PUT和/或PATCH现有实例。更好的是,您可以使用通用视图ListCreateAPIViewRetrieveUpdateAPIView通过GET检索这两个端点。

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

答案 1 :(得分:2)

我有一种情况,我有一个深度创建方法,在结束点之上有2级层次结构,所有模型都是幂等的很重要。

我覆盖了序列化程序中的验证,并手动创建。

将字段添加到顶部的类是很重要的(否则验证程序将不会运行)

layouts