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
现在,我不确定如何编写序列化程序和视图以便:
- 创建了一个新位置并return编辑了所有字段
第一次看到新地址时初始化
- 数据库中与 '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提出来。我想继续学习。
我是 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
现在,我不确定如何编写序列化程序和视图以便:
- 创建了一个新位置并return编辑了所有字段 第一次看到新地址时初始化
- 数据库中与 '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提出来。我想继续学习。