Django Rest ModelSerializer 查找或创建模式

Django Rest ModelSerializer Find or Create Pattern

我是 Django 的新手。阅读很多方法来做同样的事情——但没有在大海捞针中找到众所周知的针。一个这样的针是 Django Rest 的简单 "Find or Create" 模式。

我试图找到一个简单示例,说明如何使用 Django Rest ModelSerializer 和 CreateAPIView 方法为我的模型数据之一实现查找或创建模式。假设我有一个带有唯一字段 'address' 的模型 Location。当地址已存在于我的数据库中时,我想 return 现有实例。如果该地址不存在,我想在数据库中创建一个条目并填充该对象的其他计算值。

class Location(models.Model):
    address = models.CharField(max_length=100, unique=True,)
    thing1 = models.CharField(max_length=100, blank=True, null=True, )
    thing2 = models.CharField(max_length=100, blank=True, null=True, )

    def compute_things(self, address):
        somevalue1 = ...
        somevalue2 = ....
        return somevalue1, somevalue2

现在,我不确定如何编写序列化程序和视图以便:

  1. 创建了一个新位置并return编辑了所有字段 第一次看到新地址时初始化
  2. 数据库中与 'address' 匹配的现有位置是 return代替步骤 1

我还应该为模型定义什么?我如何编写 APIView 和 CreateSerializer 以获得正确的东西?我应该在哪里调用 compute_thing() 以填充缺失的字段。

对于序列化程序:

class LocationCreateSerializer(ModelSerializer):
    class Meta:
        model = Location

对于 APIView:

class LocationCreateAPIView(CreateAPIView):
    serializer_class = LocationCreateSerializer
    queryset = Location.objects.all()

上面的APIView和Serializer还不够我需要的。我还需要向模型、视图和序列化程序添加什么才能获得我正在寻找的行为?

我不希望视图和序列化程序 return 重复验证错误 'addresses'-- 只是现有实例而不是错误。看起来 restore_object() 已被弃用。有什么方法可以实现我所寻求的吗?

你漏掉了一件事,那就是

fields =("Here will be your models fields. That you want to serialize.") 那是在序列化程序中的 model = Location 之后。

你可以关注Django-REST-Framework

的官方文档

好的,我找到了我自己问题的答案。我不确定这是最好的解决方案;然而,对于任何需要解决方案的人来说,这就是我最终所做的:

class LocationCreateAPIView(CreateAPIView):
    serializer_class = LocationCreateSerializer
    queryset = Location.objects.all()

    def post(self, request, format=None):
        address = None
        if 'address' in self.request.data:
            address = self.request.data['address']
        else:
            return Response(status=HTTP_400_BAD_REQUEST)

        try:
            location = Location.objects.get(address=address)
            serializer = self.get_serializer(location)
            return Response(serializer.data, status=HTTP_200_OK)
        except Location.DoesNotExist:
            pass

        serializer = LocationCreateSerializer(data=self.request.data)
        if serializer.is_valid():
            somevalue1, somevalue2 = Location.compute_things(self, address=address)
            if (not somevalue1) | (not somevalue2):
                return Response(status=HTTP_400_BAD_REQUEST)

            serializer.save(address=address, thing1=somevalue1, thing2=somevalue2)
            return Response(serializer.data, status=HTTP_201_CREATED)

        return Response(status=HTTP_400_BAD_REQUEST)

如果您有更好的解决方案,请post提出来。我想继续学习。