Django模型中的类别聚类

时间:2019-05-21 16:04:35

标签: python django django-models orm categories

上下文:创建CMS

我正在寻找一种有效的方式来表示Django模型中主题的主题嵌套/相关性。现在,类别定义如下:

class Category(models.Model):
    parent        = models.ForeignKey('self', default=None, null=True, blank=True, related_name='nested_category', on_delete=models.CASCADE)
    name          = models.CharField(max_length=50, unique=True)
    nesting_level = models.IntegerField(default = 0, editable=False)

    def __init__(self, *args, **kwargs): 
        super(Category, self).__init__(*args, **kwargs)
        if self.parent != None:
            self.nesting_level = self.parent.nesting_level + 1
        elif self.parent == None:
            self.nesting_level = 0

    def __str__(self):                           
        full_path = [self.name.lower()]                                        
        k = self.parent                          

        while k is not None:
            full_path.append(k.name.lower())
            k = k.parent

        return '->'.join(full_path[::-1])

这很好。每次添加类别时,都会根据父级的nesting_level计算nesting_level。我看到了BDD中的更改(我知道,在Django中不应覆盖__init__,但稍后再讨论此问题)。

需要

说我有以下三个类别:

Code--------Python---------Django
 [1]    |     [2]     |      [3]
        |             |----Functional_Programing
        |---Java               [5]
             [4]

当点击类别 Python 时,视图不仅应在

中显示 Articles
  • code->python
  • code->python->django
  • code->python->functional_programing

因为后者也是 python相关的。当点击网址/browse/code->python/时,视图将显示类似articles = Article.objects.filter(category__in=[2, 3, 5])

这个想法行不通(我不确定为什么)

由于类别不经常更改,因此我认为在BDD本身中表示这三个结构是一个好主意,以便轻松提取子主题列表。该表将类似于:

id | name                  | nesting_level | cluster | parent
1  | Code                  | 0             | 1,2,3,5 | None
2  | Python                | 1             | 2,3,5   | 1
3  | Django                | 2             | 3       | 2
4  | Java                  | 1             | 4       | 1
5  | Functional_programing | 3             | 5       | 2

类别类,稍作修改:

class Category(models.Model):
    parent        = models.ForeignKey('self', default=None, null=True, blank=True, related_name='nested_category', on_delete=models.CASCADE)
    name          = models.CharField(max_length=50, unique=True)
    nesting_level = models.IntegerField(default = 0, editable=False)
    cluster       = models.CharField(default = "", max_length=20, editable=False)

    def __init__(self, *args, **kwargs): 
        super(Category, self).__init__(*args, **kwargs)

        self.cluster = str(self.id)
        if self.parent != None:
            self.nesting_level = self.parent.nesting_level + 1
            self.parent.cluster = "{},{}".format(self.parent.cluster,self.id)
        elif self.parent == None:
            self.nesting_level = 0

当我print时它似乎可以工作,但是更改似乎没有附加到BDD中(在开发的早期阶段: SLQlite )。我读到__init__不应出于相关的'信号原因'而在Django中被覆盖,因此我也尝试覆盖save

def save(self, *args, **kwargs):
        self.cluster = str(self.id)
        if self.parent != None:
            self.nesting_level = self.parent.nesting_level + 1
            self.parent.cluster = "{},{}".format(self.parent.cluster,self.id)
        elif self.parent == None:
            self.nesting_level = 0
        super(Category, self).save(*args, **kwargs)

这也不起作用,但是这次是因为self.id=None(<class 'NoneType'>)

我开始对这个ORM的微妙之处感到迷茫。由于可能有更简单的方法来实现我想要的目标,但是我也有兴趣了解为什么我的方法行不通,因此欢迎各种建议

0 个答案:

没有答案