дизайн базы данных для оформления заказа и таблицы заказов

#python #django #django-models #database-design

#python #django #django-модели #database-design

Вопрос:

Я разрабатываю базу данных для электронной коммерции. Я в замешательстве относительно оформления заказа и таблицы заказов. Я не уверен, нужно ли мне создавать отдельную order таблицу, когда большинство вещей уже сделано в checkout таблице.

Вот дизайн на данный момент

 class Product(ModelWithMetadata, PublishableModel):
    product_type = models.ForeignKey(
        ProductType, related_name="products", on_delete=models.CASCADE
    )
    category = models.ForeignKey(
        Category,
        related_name="products",
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
    )

class ProductVariant(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name="variants")
    variant_attributes = models.ManyToManyField(VariantAttribute, related_name="productvariants")


class Checkout(ModelWithMetadata):
    """A shopping checkout."""
    created = models.DateTimeField(auto_now_add=True)
    last_change = models.DateTimeField(auto_now=True)
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        blank=True,
        null=True,
        related_name="checkouts",
        on_delete=models.CASCADE,
    )
    email = models.EmailField()
    token = models.UUIDField(primary_key=True, default=uuid4, editable=False)
    quantity = models.PositiveIntegerField(default=0)
    billing_address = models.ForeignKey(
        Address, related_name=" ", editable=False, null=True, on_delete=models.SET_NULL
    )
    shipping_address = models.ForeignKey(
        Address, related_name=" ", editable=False, null=True, on_delete=models.SET_NULL
    )
    shipping_method = models.ForeignKey(
        ShippingMethod,
        blank=True,
        null=True,
        related_name="checkouts",
        on_delete=models.SET_NULL,
    )
    note = models.TextField(blank=True, default="")

    currency = models.CharField(
        max_length=settings.DEFAULT_CURRENCY_CODE_LENGTH,
        default=settings.DEFAULT_CURRENCY,
    )
    country = CountryField(default=get_default_country)

    discount_amount = models.DecimalField(
        max_digits=settings.DEFAULT_MAX_DIGITS,
        decimal_places=settings.DEFAULT_DECIMAL_PLACES,
        default=0,
    )
    discount = MoneyField(amount_field="discount_amount", currency_field="currency")
    discount_name = models.CharField(max_length=255, blank=True, null=True)

    voucher_code = models.CharField(max_length=12, blank=True, null=True)
    # gift_cards = models.ManyToManyField(GiftCard, blank=True, related_name="checkouts")

    objects = CheckoutQueryset.as_manager()

    class Meta:
        ordering = ("-last_change", "pk")


class CheckoutLine(models.Model):
    """A single checkout line.
    """

    checkout = models.ForeignKey(
        Checkout, related_name="lines", on_delete=models.CASCADE
    )
    variant = models.ForeignKey(
        "product.ProductVariant", related_name=" ", on_delete=models.CASCADE
    )
    quantity = models.PositiveIntegerField(validators=[MinValueValidator(1)])
  

Дополнительные вещи, которые не рассматриваются в таблице оформления заказа, касаются отслеживания заказов и возврата средств. Это потому, что я в замешательстве, если лучше использовать это также в checkout таблице или создать новую order таблицу и соответственно оформить возврат и политику отслеживания.

Если лучше использовать отдельную order таблицу, может кто-нибудь рассказать мне о преимуществах и о том, как это возможно, пожалуйста?

Комментарии:

1. Это чисто технический или практический вопрос?

2. Я намерен понять дизайн таблицы (практический) с объяснением, если требуется таблица заказов. Извините, я плохо говорю по-английски, поэтому мой вопрос может вас смутить.

Ответ №1:

Вы должны не только создать отдельную модель заказа, но и отдельную модель продукта и по-разному интегрировать вторичные затраты. Причина в следующем: заказы должны быть статической информацией по юридическим / финансовым причинам. Они записывают то, что происходило в прошлом. Он должен соответствовать цене продукта на тот момент, стоимости доставки, платежным сборам и т. Д. Вся эта информация не может быть изменена, и при оформлении заказа они связаны с объектами, которые можно изменять или даже удалять.

Для продукта вы обычно делаете что-то вроде этого:

 class PurchasedItem(models.Model):
     original_product = models.ForeignKey(Product, on_delete=models.SET_NULL, null=True)
     ...  # minimal set of product attributes that allow delivery of the order
          # with the correct item (color / size / etc) and fixed price
          # Basically flatten product variant and product attributes that are
          # relevant.
  

Таким образом, вы все равно можете выполнять повторные заказы, пока продукт все еще доступен. Нужно многое учитывать, но в основном каждый раз, когда вы хотите создать ForeignKey для элемента заказа, вы должны подумать, изменяет ли изменение связанного элемента порядок.

Итак, ваша строка заказа становится примерно такой:

 class OrderLine(models.Model):
    order = models.ForeignKey(Order, ...)
    item = models.ForeignKey(PurchasedItem, ...)
    quantity = models.PositiveIntegerField(...)
  

Модель заказа:

  • Если вы разрешаете удаление учетных записей пользователей, то Order.user должен иметь значение null.
  • Адрес доставки и выставления счетов должен быть OneToOneField, и новая копия должна создаваться каждый раз при оформлении заказа — или (лучше) — сглаживать атрибуты адреса в заказе.
  • Способ доставки: сгладить и записать окончательную цену
  • Валюта: запись обменного курса, позволяет изменять обменный курс после поступления банковской выписки
  • Страна: запишите название страны, если вы хотите сохранить ссылку на страну для статистических целей, сделайте ее нулевой. Только при моей жизни СССР, Восточная / Западная Германия, Югославия и многие другие прекратили свое существование.

Надеюсь, это поможет вам начать.

Комментарии:

1. Большое вам спасибо за ваш ответ. Теперь мне ясно, зачем мне нужна отдельная модель. Модель оформления заказа является временной.