问题: 我遇到的问题是在选择模型中获得选项的价格。这是因为,根据其他选项也在同一购物车中,将使用不同的价格来生成总额。如果该选项的 effector_option 本身位于同一个购物车中,我需要帮助我获取选项的价格,否则请使用< strong>变化,仅设置选项字段。
TempName App 模型包含:
class Section(models.Model):
title = models.CharField(max_length=20)
description = models.CharField(max_length=100)
temp = models.ForeignKey(TempName, null=False)
def __str__(self):
return self.title
def get_options(self):
return self.option_set.all()
class Option(models.Model):
name = models.CharField(max_length=120)
section = models.ForeignKey(Section, null=False)
def __str__(self):
return self.name
def get_variations(self):
return self.variation_set.all()
class Variation(models.Model):
name = models.CharField(max_length=60, blank=True, unique=True)
price = models.DecimalField(max_digits=5, decimal_places=2)
option = models.ForeignKey(Option, null=False)
effector_option = models.ForeignKey(Option, null=True, blank=True, related_name='option_effected')
def __str__(self):
return self.name
一页上可以有多个部分。每个部分可以包含许多选项,稍后可由用户选择。选定的选项将放入购物车中,该购物车将用于生成总价。
在变体模型中,字段选项只是告诉我变体属于哪个选项。然而, Varaition 模型中的 effector_option 字段将由购物车使用。
用户可以选择任意数量的选项,但是,根据用户选择的选项,其他选项可能会显示变体之前选择 effector_option 的价格。
购物车应用模型包含:
class Cart(models.Model):
owner = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True)
creation_date = models.DateTimeField(verbose_name='creation date')
checked_out = models.BooleanField(default=False, verbose_name='checked out')
class Meta:
verbose_name = 'cart'
verbose_name_plural = 'carts'
ordering = ('-creation_date',)
def __str__(self):
return unicode(self.creation_date)
def get_selections(self):
return self.selection_set.all()
class Selection(models.Model):
cart = models.ForeignKey(Cart)
option = models.ForeignKey(Option)
@property
def price(self):
return 10
购物车可以包含用户选择的多个选项。每个选择都有一个价格属性,可用于向用户显示该选项的价格,具体取决于哪个选项也在同一购物车中。
我做过什么:
获取选项的所有变体。然后遍历每个变体并检查Variation.effector_option是否包含在同一 Cart 中。如果是,则显示该价格,否则显示Variation.effector_option为空/未设置的变化内的价格。
我发现购物车中的每个选择都会调用超过26个查询。这个db模式是否需要更多规范化,或者它对于这个简单的项目是否足够好?
答案 0 :(得分:3)
我发现在购物车中为每个选择调用超过26个查询。这个db模式是否需要更多规范化,或者它对于这个简单的项目是否足够好?
我会咬人,因为我相信这个解决方案就是软件工程。这里的问题不是规范化,也不是Django。它是如何选择组织问题的。我猜测你已经陷入了一些陷阱,我将在讨论这些陷阱。首先让我们从你自己的......开始直接得到一些定义。
现在我们有这个问题吗?我的部分Option
选项可与其他Option
选项一起使用,并影响价格!混沌!我们需要Variation
为其互动提供元规则。更多查询!更多逻辑!也许...
陷阱1
让屏幕上显示的内容可以驱动您的数据模型
我在这里猜测,但使用单词Section
和Option
让我觉得你正在组织一个屏幕而不是数据库。更常见的是,企业的模型看起来如下......
Product
- 我们销售的商品(name
,base_price
,options
,option_sets
)OptionSet
- 一组选项,作为一揽子交易!想想节省的费用!(name
,group
,options
,price
,optionset_exclusions
,option_exclusions
)Option
- 点菜选项(name
,group
,price
)Purchase
- 有人想要购买的内容(product
,options
,optionsets
)现在你可能会说“我的部分怎么样了!”分段可以像挂起OptionSet
和Option
group
CharField
类型的group
一样简单。在模板中进行渲染时,您可以通过exclusions
将选项/选项集合在一起。您可以使用Option
阻止人们为OptionSets
选择有冲突的Product
和prefetch_related
。现在整个shebang可以在页面上填充,只需3个查询(正确使用Options
),并且可以简单地将选定的OptionSets
/ Variation
添加到一起以获得确定的价格
陷阱2
让你想要它的工作方式阻止它工作
现在,在您发布“这对我不起作用,我只是一片雪花!”(已经很久了)。我们经常发现,我们希望某些东西能够发挥作用的方式阻碍了它的运作。
旧的unix负责人曾经讨论过一致性,简单性和完整性的优点。共识是,即使不完整或一致,简单性也是最好的。您的原始解决方案希望使用复杂性来实现完整性。 这是一个陷阱!(感谢admiral ackbar)
e.g。这是我/我的客户的业务运作方式,因此它必须以这种方式工作
当我们寻找实现简单性的方法时,软件更便宜/更容易编写。有时这意味着要改变组织以符合软件的限制。
我可以想象对上述陈述
的反驳选项1将为您提供选项2的10%折扣。您只有静态价格!
这可以在上面的模式中建模,其中总价格等于期权1的价格+ .9(期权2的价格)。在这种情况下,我们刚刚采用Options
的概念并将其作为数据而不是行为。更简单。它更灵活。我的意思是你可以在价格上做一些复杂的3D体积计算,只是将结果渲染到你的产品架构中。还有更多问题需要考虑......
我不想手工完成所有这些配置!
自己编写一个从电子表格导入的Django管理命令。
如果_spec
之间的价格或关系发生变化怎么办?
大多数产品/价格架构都包含Option_spec
之类的_spec
概念,可让您捕获即时点购买条款。在购买商品时,Purchase
条记录与Option
相关联。这样,OptionSet
和{{1}}可以在不更改所有已连接的过去购买的情况下进行更改。
并且列表继续......
这里的要点是,如果你聪明开朗,你可以梦想的所有问题都有简单的解决方案。