How to force reverse related field unique in Django?

Viewed 19
class CartItem(models.Model):
    cart = models.ForeignKey(Cart, on_delete=models.CASCADE)
    product = models.ForeignKey(settings.PRODUCT_MODEL, on_delete=models.CASCADE)
    quantity = models.SmallIntegerField(default=1)

    class Meta:
        ordering = ["pk"]


class Select(models.Model):
    cartItem = models.ForeignKey(CartItem, on_delete=models.CASCADE)
    option = models.ForeignKey(Option, on_delete=models.CASCADE)
    choice = models.ForeignKey(Choice, on_delete=models.CASCADE)

With the above code, what I want to do is each CartItem instance has an unique select_set.

If two cartItems has the same product and select_set with the same option and choice combinations, They are considered to be same.

I've done it with select as JSONfield of dict(option as key, choice as value) in which case what i need to do is just compare their JSONfield.

class CartItem(models.Model):
    cart = models.ForeignKey(Cart, on_delete=models.CASCADE)
    product = models.ForeignKey(settings.PRODUCT_MODEL, on_delete=models.CASCADE)
    quantity = models.SmallIntegerField(default=1)
    selects = models.JSONField(default=dict)

this one is the previous JSONfield one.

cart_item, created = cart.cartitem_set.get_or_create(
    product_id=product_id, selects=selects
)

if quantity == 0:
    cart_item.delete()
else:
    cart_item.quantity = quantity
    cart_item.save()

I've tried this one filtering having only same choices.

queryset = cart.cartitem_set.filter(product_id=product_id)
for option_id, choice_id in selects.items():
    queryset = queryset.filter(select__choice=choice_id)

cart_item, created = queryset.get_or_create(
    product_id=product_id,
)

if not created:
    cart_item.quantity += quantity
else:
    cart_item.quantity = quantity

for option_id, choice_id in selects.items():
    cart_item.select_set.create(option_id=option_id, choice_id=choice_id)
cart_item.save()

is there one hit create operation like the above one? using get_or_create And if possible I want to check uniqueness on database-level.

0 Answers
Related