【问题标题】:Sub Categorized Status Choices in DjangoDjango中的子分类状态选择
【发布时间】:2019-01-09 09:12:29
【问题描述】:

假设我有一个三明治模型,我想说你想在三明治上放什么蛋白质:

class Sandwich(models.Model):
    protein_choices = (
        ('n',  'Please Choose'),
        ('e1', 'Eggplant'),
        ('e2', 'Hummus'),
        ('v1', 'Provolone'),
        ('v2', 'Egg'),
        ('p1', 'Fish'),
        ('c1', 'Beef'),
        ('c2', 'Chicken'),
        ('c3', 'Pork'),
    )
    protein = models.CharField(
        max_length=2,
        choices=protein_choices,
        default='n',
    )

我如何做出按 vEgan、Vegetarian、Pescatarian 或 Carnivore 分类的选择?

我希望能够检查它的类别(三明治是素食主义者吗[假设类别不重叠]?),并且我一直在使用 model.Manager,但我想确保所有选择都有一个类别(我认为这是缺少的环节,并且不认为测试是正确的方法)并且只选择了一个选项(已经由呈现的状态结构处理)。

这应该通过model.Form、与其他结构的1->M 关系,还是通过model.Managers 和其他方式处理?

【问题讨论】:

  • 假设类别不重叠?所以茄子会出现在素食主义者中,但不是素食主义者?这似乎很奇怪。
  • 我知道这个例子的问题,但你现在谈论的是一个不同的问题(没有分类是原子的,因此它是一个分类/分类)。尝试使用您选择的任何示例来考虑它:) 顺便说一句,茄子目前属于 vEgan 类别,我认为您的意思是转置您的评论。

标签: django django-models


【解决方案1】:

另一个选项是内存中的数据结构和接口,可将您的状态键映射到相应的类别。例如,您可以use an Enum with a category property as the basis for your Choices. 如果这些字符串之间的关系最终成为您想要在数据库中管理的东西,您可以随时重构并添加迁移。

正如您所注意到的,在您的模型中构建一个树结构,正如其他人所建议的那样,会产生很多连接。在这种情况下,查看django-treebearddjango-categories 并检查是否很有用承担这种额外的依赖是合理的。

【讨论】:

    【解决方案2】:

    我认为蛋白质和类别有单独的模型会很好。

    示例

    class Protein(models.Model):
        name = models.CharField(max_length=20)
    
    class ProteinCategory(models.Model):
        protein = models.ForeignKey(to="Protein")
        name = models.CharField(max_length=20)
    
    class Sandwich(models.Model):
        protein = models.ForeignKey(to="Protein")
    

    如果Sandwich 包含许多Protein,则在Sandwich 模型中使用ManyToManyField 而不是ForeignKey。 在ProteinCategory 模型中使用OneToOneField,如果Protein 可以在一个且只有一个ProteinCategory 中。

    【讨论】:

    • 问题说只选择了一个选项。多对多不是一种选择。
    • 这也不能保证所有的选择都在一个 [single] 类别中
    • 您在三明治中添加的每种蛋白质都有一个与之相关的类别。因此,ProteinCategory 模型。
    • 我想我明白了,也许外键放错了位置/混淆了,这让我很困惑。
    • 再看一遍,参考你要呈现给用户的表格,以创建三明治或添加新的蛋白质类别。
    【解决方案3】:

    我建议为此任务使用不同的模型。

    继续您的示例,您可以拥有蛋白质,每个蛋白质都属于一个类别(根据您在问题 cmets 中的要求):

    class ProteinCategory(models.Model):
        name = models.CharField(max_length=20)
    
    class Protein(models.Model):
        name = models.CharField(max_length=20)
        category = models.ForeignKey(to=ProteinCategory)
    

    然后您可以为每个三明治分配一种蛋白质(根据您的要求):

    class Sandwich(models.Model):
        name = models.CharField(max_length=20)
        protein = models.ForeignKey(to=Protein)
    

    这似乎解决了您的问题?

    【讨论】:

    • 我认为现在这需要 3 个连接语句才能找出三明治所在的 [子] 类别。这似乎不太优雅,但我正在尝试了解有哪些选项,这当然是一种选择。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-11
    • 2016-03-18
    • 2018-09-25
    • 2014-12-29
    • 2019-03-06
    • 1970-01-01
    相关资源
    最近更新 更多