Django

时间:2017-06-16 19:34:02

标签: django many-to-many

我有这两个模型:

class Item(models.Model):
    id = models.IntegerField(primary_key=True)
    name = models.CharField(max_length=100)
    rarity = models.CharField(max_length=3)
    craftable = models.BooleanField()

class Recipe(models.Model):
     id = models.IntegerField(primary_key=True)
     items = models.ManyToManyField(Item)

有些物品有食谱,因为它们是狡猾的,有些则不是因为它们是基础物品。 制作另一个项目所需的一些项目需要按照配方创建(它们是嵌套的,多次!)

示例:

  

项目:建筑材料

     

配方:[钢,粉笔,钢筋混凝土]

           

项目:钢筋混凝土

     

食谱:[沙子,混凝土,]

           

项目:

     

配方:[抗性石材,混凝土,树脂]< - 所有基础对象

如何创建一个显示允许我制作某个项目的所有项目树的视图?

  

结果:

     
      
  • 建筑材料

         
        
    •   
    • 粉笔

    •   
    • 钢筋混凝土

           
          
      •   
      • 混凝土

      •   
      •      
            
        • Resistant Stone

        •   
        • 混凝土

        •   
        • 树脂

        •   
      •   
    •   
  •   

我无法找到一种方法,可以在关系中尽可能深入...

1 个答案:

答案 0 :(得分:0)

您的模型不会显示特定项目使用的配方。如果您执行此类操作,则可以省略Recipe模型(已编辑以添加symmetrical = False):

class Item(models.Model):
    # django will create an id field automatically
    name = models.CharField(max_length=100)
    rarity = models.CharField(max_length=3)
    ingredients = models.ManyToManyField('self', symmetrical=False)

    def is_base(self):
        return not self.ingredients

    def is_craftable(self):
        return not self.is_base()

    def build_recipe(self):
        recipe = []
        for ingredient in self.ingredients.all():
            recipe.append(ingredient.name)
            if ingredient.is_craftable():
                recipe.append(ingredient.build_recipe())
        return recipe

要显示嵌套的食谱,您可以在模板中使用内置的unordered_list过滤器:

<h1>Recipe for {{ item.name }}</h1>
<ul>
    {{ item.build_recipe|unordered_list }}
</ul>