如何为任意嵌套的类别和子类别建模?

时间:2019-09-26 14:51:33

标签: python django

我正在寻找一种有效的方法来为电子商务目的在Django中为产品类别和任意嵌套的子类别建模。我现在拥有的东西现在可以工作,但是当您要查询以获取全部书籍时,这成为一个问题,因为您需要首先递归查找“ Book”的所有子类别,然后从这些子类别中获取所有书籍。

假设您有一本小学数学教科书,它应该属于:

书籍->教科书->小学

...并且要获得所有书籍,就必须像这样对怪物进行查询:

>>> from products.models import Product, Category
>>> from django.db.models import Q
>>> c = Category(name='Books')
>>> c.save()
>>> c1 = Category(name='Textbooks', parent=c)
>>> c1.save()
>>> c2 = Category(name='Primary school', parent=c1)
>>> c2.save()
>>> p = Product(title='Math textbook', description='Math textbook for 4th grade', price=20, category=c2)
>>> p.save()
>>> Product.objects.filter(Q(category__name='Books') | Q(category__parent__name='Books') | Q(category__parent__parent__name='Books'))
<QuerySet [<Product: Product object (3)>]>

...效率低下,您无法事先知道类别的嵌套方式。

这是简化模型的样子:

class Product(models.Model):
    title = models.CharField(max_length=200)
    description = models.TextField()
    price = models.DecimalField(decimal_places=2, max_digits=10)
    category = models.ForeignKey('Category', on_delete=models.CASCADE)


class Category(models.Model):
    parent = models.ForeignKey('self', null=True, blank=True, on_delete=models.CASCADE)
    name = models.CharField(max_length=255)

1 个答案:

答案 0 :(得分:0)

执行此操作的一种方法是将另一个字段添加到类别模型,该字段具有类别的层次结构名称,例如Books.Textbooks.Primary_school,然后使用诸如SimpleForwardingServerCallListener之类的查询进行搜索。您可以通过覆盖保存功能来自动填充full_name字段。 因此,类别类别变为

Product.objects.filter(category__full_name__icontains='Books')