简体   繁体   English

我如何为 Django 中的类别制作好的模型?

[英]How can i make good models for categories in django?

im trying to make an online menu.我正在尝试制作在线菜单。 i want to make a category, sub category and items that goes in one of those.我想制作一个类别、子类别和属于其中之一的项目。

I mean, an item can be on a category like "sushi" -> nameofsushi, or be in a sub category like sushi -> avocado rolls -> nameofsushi.我的意思是,一个项目可以属于“寿司”-> nameofsushi 这样的类别,或者属于像寿司这样的子类别 -> 鳄梨卷 -> nameofsushi。

i have something like this in my models.py but is there a better way to do it?我的models.py中有类似的东西,但有更好的方法吗?

class Category(models.Model):
    name = models.CharField(max_length=200)
    description = models.TextField(max_length=500, verbose_name='Descripción', blank=True, null=True)
    parent = models.ForeignKey('self', related_name='children', null=True, blank=True, on_delete=models.CASCADE)
    
    def __str__(self):
        return 'Category: {}'.format(self.name)

class MenuItem(models.Model):
    name = models.CharField(max_length=200)
    image = models.ImageField(upload_to='menu_images/', null=True, blank=True)
    description = models.TextField(blank=True, null=True)
    price = models.DecimalField(max_digits=6, decimal_places=0)
    other_Price = models.DecimalField(max_digits=6, decimal_places=0, null=True, blank=True)
    categories = models.ManyToManyField('Category', related_name='item', null=True, blank=True)
    
    def __str__(self):
        return 'MenuItem: {}'.format(self.name)

You need to carefully think about your model design.您需要仔细考虑您的模型设计。 The way you have designed categories allows you to have unlimited sub-categories.您设计类别的方式允许您拥有无限的子类别。 Do you really need that flexibility?你真的需要这种灵活性吗? Because it comes at the cost of complexity.因为它是以复杂性为代价的。 Think about how you will be interacting with the models.想想你将如何与模型交互。

With your current design, it would be challenging to render in a Django template without preprocessing it in Python using some gnarly recursion, because you have no way apriori to know how many nested sub categories you have.使用您当前的设计,在 Django 模板中渲染而不使用一些粗糙的递归在 Python 中对其进行预处理将是一项挑战,因为您无法先验地知道您有多少嵌套的子类别。 You could have sub-category, sub-sub-category, sub-sub-sub-category and so on.您可以有子类别、子子类别、子子子类别等等。

Also, querying your models will be complicated.此外,查询您的模型会很复杂。 Say you have 'Cat1'->'Sub-cat1'->'Sub-sub-cat1'->'menuitem1' .假设您有'Cat1'->'Sub-cat1'->'Sub-sub-cat1'->'menuitem1' How do you find all menu items that are a descendant of 'sub-cat1 '?您如何找到'sub-cat1 ”的后代的所有菜单项? All I can think of is MenuItem.objects.filter(parent__parent=subcat1_obj) .我能想到的只有MenuItem.objects.filter(parent__parent=subcat1_obj) Not very Pythonic or clear to a reader.对读者来说不是很 Pythonic 或清晰。 And you run into problems as you dont know how many layers of sub-categories you have.你会遇到问题,因为你不知道你有多少层子类别。

Or how do you get just the menu categories?或者你如何只获得菜单类别? Category.objects.filter(parent=None) . Category.objects.filter(parent=None) Its not obvious from this code what we are talking about.从这段代码中看不出我们在说什么。

I would, if your use-case allows it, simplify your model design in this way:如果您的用例允许,我会以这种方式简化您的模型设计:

class MenuCategory(models.Model):
    category = models.ForeignKey(Category, ...)
    ...

class MenuSubCategory(models.Model):
    menu_category = models.ForeignKey(MenuCategory, ...)
    ...

class MenuItem(models.Model):
    menu_categories = models.ManyToManyField(MenuCategory, ...)
    menu_subcategories = models.ManyToManyField(MenuSubCategory, ...)
    ...

Now rendering your models in a template would be straight forward (given context['menu_categories'] = MenuCategory.objects.all() ):现在在模板中渲染你的模型将是直接的(给定context['menu_categories'] = MenuCategory.objects.all() ):

{% for cat in menu_categories %}
  {% for item in cat.menuitem_set.all %}
    {{ item }}
  {% endfor %}
  {% for subcat in cat.menusubcategory_set.all %}
    {% for item in subcat.menuitem_set.all %}
      {{ item }}
    {% endfor %}
  {% endfor %}
{% endfor %}

Now querying your models will also be more clear.现在查询您的模型也会更加清晰。 You could also if needed add a Menu model and have different menus.如果需要,您还可以添加Menu模型并具有不同的菜单。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM