From 8d51981368b5a3edb6fd7b07927b9febf6bc6621 Mon Sep 17 00:00:00 2001 From: Gabriel Augendre Date: Thu, 5 May 2022 19:11:30 +0200 Subject: [PATCH] Add unique constraint to baskets --- .../commands/generate_dummy_baskets.py | 16 +++++++++++--- ...08_basketitem_unique_product_per_basket.py | 22 +++++++++++++++++++ src/purchase/models.py | 5 ++++- 3 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 src/purchase/migrations/0008_basketitem_unique_product_per_basket.py diff --git a/src/purchase/management/commands/generate_dummy_baskets.py b/src/purchase/management/commands/generate_dummy_baskets.py index d84c220..e09d95d 100644 --- a/src/purchase/management/commands/generate_dummy_baskets.py +++ b/src/purchase/management/commands/generate_dummy_baskets.py @@ -2,6 +2,7 @@ import random from datetime import timedelta import freezegun +import numpy as np from django.core.management import call_command from django.core.management.base import BaseCommand from django.utils.timezone import now @@ -39,10 +40,19 @@ class Command(BaseCommand): if random.random() < 0.99: method = random.choices(payment_methods, weights=methods_weights)[0] basket = Basket.objects.create(payment_method=method) + items_in_basket = int(random.normalvariate(3, 2)) + if items_in_basket > len(products): + items_in_basket = len(products) + if items_in_basket < 1: + items_in_basket = 1 + selected_products = np.random.choice( + products, + size=items_in_basket, + replace=False, + p=np.asarray(products_weights) / sum(products_weights), + ) items = [] - item_count = int(random.normalvariate(3, 2)) - for _ in range(item_count): - product: Product = random.choices(products, weights=products_weights)[0] + for product in selected_products: items.append( BasketItem( product=product, diff --git a/src/purchase/migrations/0008_basketitem_unique_product_per_basket.py b/src/purchase/migrations/0008_basketitem_unique_product_per_basket.py new file mode 100644 index 0000000..bb98f7c --- /dev/null +++ b/src/purchase/migrations/0008_basketitem_unique_product_per_basket.py @@ -0,0 +1,22 @@ +# Generated by Django 4.0.4 on 2022-05-05 16:46 + +import django.db.models.expressions +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("purchase", "0007_alter_basketitem_unit_price_cents"), + ] + + operations = [ + migrations.AddConstraint( + model_name="basketitem", + constraint=models.UniqueConstraint( + django.db.models.expressions.F("product"), + django.db.models.expressions.F("basket"), + name="unique_product_per_basket", + ), + ), + ] diff --git a/src/purchase/models.py b/src/purchase/models.py index 38a399a..e909800 100644 --- a/src/purchase/models.py +++ b/src/purchase/models.py @@ -3,7 +3,7 @@ from __future__ import annotations import hashlib from django.db import models -from django.db.models import Avg, Count, F, Sum +from django.db.models import Avg, Count, F, Sum, UniqueConstraint from django.db.models.functions import Coalesce from django.urls import reverse from django.utils.translation import gettext @@ -217,3 +217,6 @@ class BasketItem(Model): class Meta: verbose_name = _("basket item") verbose_name_plural = _("basket items") + constraints = [ + UniqueConstraint("product", "basket", name="unique_product_per_basket") + ]