Search code examples
djangoapidjango-modelsdjango-rest-frameworkdjango-serializer

Django: Check if an instance exists before creating


I have two models Purchaser and paymentInvoice, I want to make sure i don't create a duplicate Purchaser object when i'm creating a new paymentInvoice for the same Purchaser individual/instance.

Basically i have a Purchaser by the name Becky, so when i want to create an invoice for Becky 1st i want to make sure if the name Becky exists in Purchaser if it does, create paymentInvoice object with Becky taking the field invoiceOwner. If Becky doesn't exist in Purchaser, create an instance of that purchaser in Purchaser then use that instance name to create paymentInvoice object.

Models file

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

Serializers file

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)

Views file

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

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

POST request in Postman for the model paymentInvoice

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

My way is not working, i get the error from PostMan

MultipleObjectsReturned at /api/clients/invoice/ get() returned more than one Purchaser -- it returned 2!


Solution

  • You can first check for the record if not found then create one like below

        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)