【问题标题】:Django: Check if an instance exists before creatingDjango:在创建之前检查实例是否存在
【发布时间】:2020-08-06 19:30:08
【问题描述】:

我有两个模型 PurchaserpaymentInvoice,我想确保在为相同的 Purchaser 个人/实例创建新的 paymentInvoice 时不会创建重复的 Purchaser 对象.

基本上我有一个名为 BeckyPurchaser,所以当我想为 Becky 创建发票时,我首先要确定名称是否为 >Becky 存在于 Purchaser 中,如果存在,则创建 paymentInvoice 对象,Becky 采用字段 invoiceOwner。如果 BeckyPurchaser 中不存在,请在 Purchaser 中创建该购买者的实例,然后使用该实例名称创建 paymentInvoice 对象。

模型文件

class Purchaser(models.Model):
    name = models.CharField(max_length=50)
    phone = models.CharField(max_length=20)
    email = models.EmailField(max_length=255, blank=True, null=True)
    image = models.ImageField(default='default.png', upload_to='customer_photos/%Y/%m/%d/')
    data_added = models.DateField(default=datetime.date.today)

    def __str__(self):
        return self.name


class paymentInvoice(models.Model):

    invoiceNo = models.CharField(max_length=50, unique=True, default=increment_invoice_number)
    invoiceOwner = models.ForeignKey(Purchaser, on_delete=models.CASCADE, related_name="invoice_detail")
    product = models.CharField(max_length=50, blank=True)
    date = models.DateField(default=datetime.date.today)
    quantity = models.PositiveSmallIntegerField(blank=True, default=1)
    payment_made = models.IntegerField(default=0)

    def __str__(self):
        return self.invoiceOwner.name

序列化器文件

class paymentInvoiceSerializer(serializers.ModelSerializer):
    invoiceOwner = purchaserSerializer(many=False)
    invoiceOwner = serializers.CharField(source='invoiceOwner.name')

    class Meta:
        model = paymentInvoice
        fields = '__all__'

    def create(self, validated_data):
        purchaser_data = validated_data.pop("invoiceOwner")

        purchaser, _ = Purchaser.objects.get_or_create(**purchaser_data).first()
        validated_data.update({"invoiceOwner": purchaser})

        return paymentInvoice.objects.create(**validated_data)

查看次数文件

class PurchaserListCreateView(ListCreateAPIView):
    serializer_class = purchaserSerializer
    queryset = Purchaser.objects.all()

class paymentInvoiceListCreateView(ListCreateAPIView):
    serializer_class = paymentInvoiceSerializer
    queryset = paymentInvoice.objects.all().order_by('-date')

POST 在 Postman 中请求模型 paymentInvoice

{
    "invoiceOwner":"Becky",
    "product": "Lix",
    "quantity": 1,
    "payment_made": 3000
}

我的方法不起作用,我从 PostMan 收到错误

MultipleObjectsReturned 在 /api/clients/invoice/ get() 返回了多个 Purchaser -- 它返回了 2 个!

【问题讨论】:

    标签: django api django-models django-rest-framework django-serializer


    【解决方案1】:

    如果没有找到,你可以先检查记录,然后像下面这样创建一个

        def create(self, validated_data):
            purchaser_data = validated_data.pop("invoiceOwner")
    
            purchaser = Purchaser.objects.filter(**purchaser_data).first()
            if purchaser is None:
                 purchaser = Purchaser.objects.create(**purchaser_data)
            validated_data.update({"invoiceOwner": purchaser})
    
            return paymentInvoice.objects.create(**validated_data)
    

    【讨论】:

    • 最好使用.exists()而不是.first()
    • @ArakkalAbu 不,他也需要对象 .exists 返回一个布尔值,所以它不起作用
    【解决方案2】:

    可能 get_or_create 也应该工作,只是我认为你应该重新定义 get_or_create 而不是创建方法。

      def get_or_create(self):
       purchaser_data = validated_data.pop("invoiceOwner")
       purchase,created = Purchase.objects.get_or_create(**purchaser_data)
       validated_data.update({"invoiceOwner": purchaser})
       payment_invoice = paymentInvoice.objects.create(**validated_data)
       return payment_invoice,created
    

    在视图中:

    model_serializer = paymentInvoiceSerializer(data=request.data)
    if model_serializer.is_valid():
       payment_invoice,_ = model_serializer.get_or_create()
    

    【讨论】:

    • 你能使用 get_or_create 执行实现吗?我很好奇,因为我的没有工作
    • 你能分享一下吗
    • get_or_create 将通过 MultipleObjectsReturned 错误,因为该查询有多个购买者数据
    • 是的,是的,你认为问题是你应该重新定义 get_or_create 方法而不是 cretae,我会问你在哪里使用 create 方法
    猜你喜欢
    • 1970-01-01
    • 2020-07-29
    • 2013-09-03
    • 1970-01-01
    • 2015-03-28
    • 2011-08-21
    • 1970-01-01
    • 2019-01-17
    • 1970-01-01
    相关资源
    最近更新 更多