python - 在批量python中创建资源时如何跳过现有对象实例
Posted
技术标签:
【中文标题】python - 在批量python中创建资源时如何跳过现有对象实例【英文标题】:How to skip an existing object instance when creating resources in bulk python 【发布时间】:2019-06-06 03:52:57 【问题描述】:我正在尝试批量创建资源。在创建资源时,我有 matric_no
必须是唯一的。如果现有matric_no
的值与一些新条目一起上传,我会收到完整性错误 500,因为该值已经存在并且它会阻止创建其余值。如何遍历这些值,然后检查该值是否存在,然后跳过以便可以填充其他值?这是我的代码:
**models.py**
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
@python_2_unicode_compatible
class Undergraduate(models.Model):
id = models.AutoField(primary_key=True)
surname = models.CharField(max_length=100)
firstname = models.CharField(max_length=100)
other_names = models.CharField(max_length=100, null=True, blank=True)
card = models.CharField(max_length=100, null=True, blank=True)
matric_no = models.CharField(max_length=20, unique=True)
faculty = models.CharField(max_length=250)
department_name = models.CharField(max_length=250)
sex = models.CharField(max_length=8)
graduation_year = models.CharField(max_length=100)
mobile_no = models.CharField(max_length=150, null=True, blank=True)
email_address = models.CharField(max_length=100)
residential_address = models.TextField(null=True, blank=True)
image = models.CharField(max_length=250,
default='media/undergraduate/default.png', null=True, blank=True)
def __str__(self):
return "Request: ".format(self.matric_no)
***serializers.py***
from .models import Undergraduate
from .models import Undergraduate
class UndergraduateSerializer(serializers.ModelSerializer):
class Meta:
model = Undergraduate
fields ='__all__'
class CreateListMixin:
"""Allows bulk creation of a resource."""
def get_serializer(self, *args, **kwargs):
if isinstance(kwargs.get('data', ), list):
print(list)
kwargs['many'] = True
return super().get_serializer(*args, **kwargs)
**api.py**
from .models import Undergraduate
from rest_framework.viewsets import ModelViewSet
from .serializers import CreateListMixin,UndergraduateSerializer
class UndergraduateViewSet(CreateListMixin, ModelViewSet):
queryset = Undergraduate.objects.all()
serializer_class = UndergraduateSerializer
permission_classes = (permissions.IsAuthenticated,)
**urls.py**
from rest_framework.routers import DefaultRouter
from .api import UndergradMassViewSet
router=DefaultRouter()
router.register(r'ug', UndergradMassViewSet)
这是更新后的serializer.py
class UndergraduateSerializer(serializers.ModelSerializer):
class Meta:
model = Undergraduate
fields = ('id', 'surname', 'firstname', 'other_names', 'card','matric_no', 'faculty', 'department_name', 'sex', 'graduation_year', 'mobile_no', 'email_address', 'residential_address')
def create(self, validated_data):
created_ids = []
for row in validated_data:
try:
created = super().create(row)
created_ids.append(created.pk)
except IntegrityError:
pass
return Undergraduate.objects.filter(pk__in=[created_ids])
这就是我现在移动它的方式 序列化器.py
class UndergraduateSerializer(serializers.ModelSerializer):
def create(self, validated_data):
created_ids = []
for row in validated_data:
try:
created = super().create(row)
created_ids.append(created.pk)
except IntegrityError:
pass
return Undergraduate.objects.filter(pk__in=[created_ids])
class Meta:
model = Undergraduate
fields = ('id', 'surname', 'firstname', 'other_names', 'card','matric_no', 'faculty', 'department_name', 'sex', 'graduation_year', 'mobile_no', 'email_address', 'residential_address')
read_only_fields = ('id',)
当发送的列表已经存在matric_no时,返回500 ListSeriaizer is not iterable
【问题讨论】:
更新的序列化程序出现什么错误? 错误代码:500 List Serializer 对象不可迭代 不要将代码放在 Meta 类中。直接放到序列化器类中 @ChiomaIgbokwe 有什么改善吗?? @Ken4scholars 还没有,同样的错误,ListSerializer 对象不可迭代 【参考方案1】:你必须在你的序列化器中实现一个自定义的create()
方法来处理这种情况,因为序列化器的默认创建方法需要一个对象。
不过,这里有几个设计决策需要考虑:
-
您可以使用bulk_create,但它有很多文档中列出的警告,并且由于插入是在一次提交中完成的,因此仍然会引发完整性错误。这里唯一的优势是速度
您可以遍历每个对象并单独创建它们。这将解决完整性问题,因为您可以捕获完整性异常并继续前进。在这里你会在 1 内失去速度
您还可以在继续创建之前检查 validate 方法中的完整性问题。这样,您可以立即向客户端返回错误响应,其中包含有关违规 ro 的信息。如果一切正常,那么您可以使用 1 或 2 来创建对象。
就个人而言,我会选择 2(也可以选择 3)。假设您也决定选择它,您的序列化程序的 create 方法应如下所示:
def create(self, validated_data):
created_ids = []
for row in validated_data:
try:
created = super().create(row)
created_ids.append(created.pk)
except IntegrityError:
pass
return Undergraduate.objects.filter(pk__in=[created_ids])
所以在这种情况下,只有创建的对象会作为响应返回
【讨论】:
我尝试了自定义创建我仍然得到 500 ListSerializer object is not iterable 请贴出代码。我怀疑您正在尝试迭代序列化程序对象而不是迭代validated_data以上是关于python - 在批量python中创建资源时如何跳过现有对象实例的主要内容,如果未能解决你的问题,请参考以下文章