django - 在批量 python 中创建资源时如何跳过现有对象实例

我正在尝试批量创建资源。创建资源时,我的 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

最佳答案

您肯定必须在您的序列化程序中实现一个自定义的 create() 方法来处理这种情况,因为序列化程序的默认创建方法需要一个对象。

尽管如此,这里有几个设计决策需要考虑:

  1. 您可以使用 bulk_create但是它有很多在文档中列出的注意事项并且它仍然会引发完整性错误,因为插入是在一次提交中完成的。这里唯一的优势是速度
  2. 您可以遍历每个对象并单独创建它们。这将解决完整性问题,因为您可以捕获完整性异常并继续前进。在这里你将失去 1 秒的速度
  3. 您还可以在继续创建之前检查验证方法中的完整性问题。通过这种方式,您可以立即向客户端返回一个错误响应,其中包含有关违规 ro 的信息。如果一切正常,那么您可以使用 1 或 2 创建对象。

就我个人而言,我会选择 2(也可以选择 3)。假设您也决定选择它,那么您的序列化程序的创建方法应该如下所示:

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])

所以在这种情况下,只有创建的对象会作为响应返回

https://stackoverflow.com/questions/54142896/

相关文章:

c# - 在 C# .NET Core 的断言有效负载中使用自定义数据为第 3 方应用程序创建 SA

django - 使用 django 和 firestore,非关系数据库

github - 不存在 Jira 票证时如何阻止 GitHub 拉取请求

python - Apache Beam python Bigquery 将流式插入更改为批量插入?

c# - Selenium Firefox 不添加扩展

javascript - Laravel/Vue.js项目中如何使用Vuesax上传组件?

php - symfony 4 正在创建发布请求

javascript - TypeORM M2O O2M关系使用级联插入时外键为空

javascript - 如何在计算属性更改时更改数据?

scikit-learn - 使用类权重的网格搜索和 KerasClassifier