使用 Django REST 框架进行批量 POST 时检查记录是不是存在
Posted
技术标签:
【中文标题】使用 Django REST 框架进行批量 POST 时检查记录是不是存在【英文标题】:Check if record exists when bulk POST'ing with Django REST Framework使用 Django REST 框架进行批量 POST 时检查记录是否存在 【发布时间】:2021-11-16 03:39:53 【问题描述】:我有一个字典列表,我使用json.dumps()
将其解析为 JSON。我现在想使用 Django REST 框架将此数据发布到我的数据库。
# Example Data to POST
[
"key_1":"data_1",
"key_2":"data_2",
,
"key_1":"data_1",
"key_2":"data_2",
,
"key_1":"data_3",
"key_2":"data_4",
]
如果我们假设所有条目都是唯一的(上面的示例数据集并非如此),我们可以成功地批量发布此数据:
# models.py
class data(models.Model):
key_1 = models.CharField(max_length=64, blank=True, null=True)
key_2 = models.CharField(max_length=64, blank=True, null=True)
class Meta:
unique_together = (( "key_1", "key_2"))
# serializers.py
class dataSerializer(serializers.ModelSerializer):
class Meta:
model = data
fields = '__all__'
# views.py
class dataViewSet(viewsets.ModelViewSet):
queryset=data.objects.all()
serializer_class=dataSerializer
filter_backends=[DjangoFilterBackend]
filterset_fields=['key_1', 'key_2']
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data, many=isinstance(request.data,list))
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
# Initiating the POST request
api_url="localhost:8000/app/api/"
requests.post(
f"api_urldata/",
data=my_json_serialised_data,
headers=headers
)
但是,如果数据库中已经存在一些记录,这将失败(“字段必须是唯一的”)。
根据示例数据,列表中的条目偶尔会出现在数据库中,因此我希望避免 POST 重复(基于模型中的字段组合;我已将 unique_together
指定为明确说明哪些字段)。
在处理批量 POST 时,检查记录是否存在以及(如果存在)跳过它的最佳 DRF 方法是什么?我应该使用viewsets.ModelViewSet
并覆盖该类中的create()
方法吗?还是有更好的方法?我注意到there are several ways to create records in DRF,所以当我们处理上面示例中的一批数据时,我正在寻求最好的方法。
【问题讨论】:
ModelViewSet 并覆盖 create() 方法是一种过滤掉所需数据的方法,但我也想知道最好的方法。 【参考方案1】:要解决这个问题,您可以使用custom list serializer
来获取经过验证的数据作为列表,然后支持使用bulk_create
批量创建data
对象。
此外,您可以使用 bulk_create 的 ignore_conflicts
忽略约束错误(如您的情况下的唯一约束):
在支持它的数据库上(除 Oracle 之外的所有数据库),将 ignore_conflicts 参数设置为 True 会告诉数据库忽略插入任何违反约束的行(例如重复唯一值)的失败。启用此参数将禁用在每个模型实例上设置主键(如果数据库通常支持它)。
所以总而言之,您可以执行以下操作:
class dataListSerializer(serializers.ListSerializer)
def create(self, validated_data):
return data.objects.bulk_create([
data(**validated) for validated in validated_data
], ignore_conflicts=True)
class dataSerializer(serializers.ModelSerializer):
class Meta:
model = data
fields = '__all__'
list_serializer_class = dataListSerializer
当many=True
在序列化程序中被标记时,dataListSerializer
的创建将被使用,而不是dataSerializer
,后者将支持上述批量创建。
【讨论】:
以上是关于使用 Django REST 框架进行批量 POST 时检查记录是不是存在的主要内容,如果未能解决你的问题,请参考以下文章
使用 Django Rest 框架进行 JWT 令牌身份验证
使用 django rest 框架进行单点登录服务的任何可能方式?
是否可以在 django rest 框架序列化程序中使用重用 django 表单进行验证?