我是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
现在,我不确定如何编写序列化程序并查看以下内容:
我还应该为模型定义什么?如何编写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()。有没有办法完成我想要的东西?
答案 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)
如果您有更好的解决方案,请发布。我想继续学习。