我正在寻找一种有效的方式来表示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 时,视图不仅应在
中显示 Articlescode->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的微妙之处感到迷茫。由于可能有更简单的方法来实现我想要的目标,但是我也有兴趣了解为什么我的方法行不通,因此欢迎各种建议。