我有以下型号:
Basket
和Fruit
Basket
可以包含多个Fruit
个对象,而Fruit
属于单个Basket
。每个Fruit
都可以手动排序,以便在列出时,它们会显示保存顺序。到现在为止还挺好。
class Basket (models.Model):
# A fruit basket
name = models.CharField(max_length=100)
is_virtual = models.BooleanField(default=False)
# This is just a badly constructed example of how a list
# of basket primary keys are saved when creating the virtual basket
# This is only for demonstration purposes to solve the overall modelling issue
virtual_baskets = models.TextField(null=True)
class Fruit (models.Model):
# The basket this fruit belongs to
basket = models.ForeignKey("Basket", related_name="fruits", on_delete=models.CASCADE)
# Manually sorted order
order = models.PositiveIntegerField(default=0)
然而,Basket
上有一个名为is_virtual
的标志,它允许用户从现有的真实篮子中创建虚拟组合篮子,在这种篮子中你最终会略微违反规则:虚拟篮子实际上可以将两个现有的Baskets
和Fruit
两个篮子组合在一起。我需要能够允许用户手动对这些篮子中的Fruit
进行排序和重新排序,而不会覆盖原始篮子中的排序。
举个例子:
Basket A
按顺序包含:Apple,Banana
Basket B
按顺序包含:Orange,Grapes
我现在想创建一个虚拟Basket C
,它会像A和B一样展示水果:
Apple,Grapes,Banana,Orange
要注意的一个注意事项:虚拟篮子只是将各种其他篮子的结果组合在一起。对于用户来说,它仍然是一个有效的篮子,他们应该能够重新订购水果。
如何建立这种排序关系?我正在考虑添加一个新模型:
class FruitAppearance (models.Model):
# The basket this appearance is tied to
basket = models.ForeignKey("Basket", related_name="manually_sorted_fruits", on_delete=models.CASCADE)
# The fruit it represents
fruit = models.ForeignKey("Fruit", on_delete=models.CASCADE)
# Order
order = models.PositiveIntegerField(default=0)
我认为是对的吗?有没有更好的办法?我应该在现有的Fruit
和Basket
模型中使用ManyToManyField吗?
答案 0 :(得分:0)
我建议如下。 将您的模型分开篮子和虚拟篮子,结果删除虚拟场。
因此每个Fruit可以属于一个Basket(ForeignKey),但同时属于多个Virtual Baskets(ManyToManyField)。在manytomany字段中使用参数throught并包含另一个模型,该模型将仅存储特定虚拟购物篮的水果顺序。
class Fruit (models.Model):
# The basket this fruit belongs to
basket = models.ForeignKey("Basket", related_name="fruits", on_delete=models.CASCADE)
virtual_basket = models.ManyToManyField(Fruit, through='FruitOrdering')
# Manually sorted order
order = models.PositiveIntegerField(default=0)
答案 1 :(得分:0)
class Basket(models.Model):
name = models.CharField(max_length=100)
fruits = models.ManyToMany("Fruit", through="FruitBasket")
...
class Fruit(models.Model):
...
class FruitBasket(models.Model:
basket = models.ForeignKey("Basket", on_delete=models.CASCADE)
fruit = models.ForeignKey("Fruit", on_delete=models.CASCADE)
order = models.PositiveIntegerField(default=0)
...
通过这种方式,您可以获得一些数据冗余,但可以为每个购物篮中的水果设置不同的订单号。