Django Rest ModelSerializer查找或创建模式

时间:2016-08-04 19:27:37

标签: python django rest serialization views

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

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

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. 创建一个新位置并返回所有字段 在第一次看到新地址时初始化
  2. 匹配'地址'的现有位置在数据库中 代替第1步返回
  3. 我还应该为模型定义什么?如何编写APIView和CreateSerializer来获得正确的东西?我应该在哪里调用compute_thing()以填充缺少的字段。

    对于序列化程序:

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

    对于APIView:

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

    上面的APIView和Serializer不足以满足我的需求。还有什么我需要添加到模型,View和Serializer来获得我正在寻找的行为?

    我不希望View和Serializer为重复的地址返回验证错误 - 只是现有的实例,而不是错误。看起来不推荐使用restore_object()。有没有办法完成我想要的东西?

2 个答案:

答案 0 :(得分:0)

你错过了一件事,就是

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

您可以按照Django-REST-Framework

的官方文件进行操作

答案 1 :(得分:0)

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

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)

如果您有更好的解决方案,请发布。我想继续学习。