Как заставить обратное связанное поле быть уникальным в Django?

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)

С помощью приведенного выше кода я хочу добиться того, чтобы каждый экземпляр CartItem имел уникальный select_set.

Если два cartItems имеют одинаковый продукт и select_set с одинаковыми комбинациями опций и выбора, они считаются одинаковыми.

Я сделал это с select как JSONfield из dict(option как ключ, choice как значение), в этом случае то, что мне нужно сделать, это просто сравнить их 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)

это предыдущий JSONfield.

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

Я пробовал эту фильтрацию, имея только те же варианты.

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

существует ли одна операция создания, подобная вышеуказанной? используя get_or_create И если возможно, я хочу проверить уникальность на уровне базы данных.

Вернуться на верх