#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. Большое вам спасибо за ваш ответ. Теперь мне ясно, зачем мне нужна отдельная модель. Модель оформления заказа является временной.