gpt4 book ai didi

python - django-mptt 中的动态顺序

转载 作者:太空狗 更新时间:2023-10-29 20:29:14 24 4
gpt4 key购买 nike

我正在为我的评论应用程序使用一个 django-mptt 包,我有以下模型:

class Comment(MPTTModel):
content = models.TextField(verbose_name='Treść')
author = models.ForeignKey(AUTH_USER_MODEL, verbose_name='Autor', blank=False, null=True)
is_deleted = models.BooleanField(verbose_name='Komentarz usunięty', default=False,
help_text='Zaznacz, aby usunąć komentarz')

ip = models.GenericIPAddressField(default=0, verbose_name='Adres IP')

content_type = models.ForeignKey(ContentType, verbose_name='Typ obiektu')
object_id = models.PositiveIntegerField(verbose_name='ID obiektu')
content_object = GenericForeignKey('content_type', 'object_id')
parent = TreeForeignKey('self', null=True, blank=True, related_name='children', db_index=True)
hotness = models.FloatField(default=0)

created_at = models.DateTimeField(auto_now_add=False, verbose_name='Data dodania')

updated_at = models.DateTimeField(auto_now=True, verbose_name='Aktualizacja')

class MPTTMeta:
order_insertion_by = ('-hotness', '-created_at')

class Meta:
verbose_name = 'Komentarz'
verbose_name_plural = 'Komentarze'

def __unicode__(self):
if len(self.content) > 50:
return self.content[:50] + '...'
else:
return self.content

我想让用户可以按热度或创建日期对评论树进行排序。是否可以从 View 中编辑 order_insertion_by 字段以生成 2 种类型的排序(按日期、按热度)?感谢您的帮助。

最佳答案

Modified Preorder Tree Traversal (MPTT) 是一种使用左(lft in mptt)和右(rgt)查询检索树结构的方法) 编号如图所示 http://sitepointstatic.com/graphics/sitepoint_numbering.gif .

定义多个 order_insertion_by 将执行以下操作(根据 mptts 评论):

"""
Creates a filter which matches suitable right siblings for ``node``,
where insertion should maintain ordering according to the list of
fields in ``order_insertion_by``.

For example, given an ``order_insertion_by`` of
``['field1', 'field2', 'field3']``, the resulting filter should
correspond to the following SQL::

field1 > %s
OR (field1 = %s AND field2 > %s)
OR (field1 = %s AND field2 = %s AND field3 > %s)

"""

如果我没有理解错的话,order_insertion_by 指定兄弟元素的顺序,表示父元素的子元素(而非后代)。如果你想要两个不同的顺序,lftrgt 也必须改变,因此它是第二棵树。这不包括在 mptt 中。

你还是可以的

Comment.objects.all().order_by('-hotness')

但是你会失去树结构。通常不可能维护树结构并通过其他方式对整棵树进行排序,例如热度。假设您有以下内容:

Comment1 (hotness 0)
Comment2 (hotness 2, child of Comment1)
Comment3 (hotness 1)

这会导致

Comment2
Comment3
Comment1

它是有序的,但是 Comment2 没有附加到 Comment1 上。如果您想在兄弟级别的基础上使用 order_insertion_by 定义的其他内容进行排序,以获得以下内容:

Comment3
Comment1
Comment2

也许可以编写一个新的模板标记,如 {% recursetree objects -hotness %} 迭代并重新排序 children 元素并返回新树.它仍然是一个数据库查询 - 但我无法估计性能损失。

您必须按如下方式创建 mptt 并编辑 mptt_tags.py:

class RecurseTreeNode(template.Node):
def __init__(self, template_nodes, queryset_var, order_var=None):
self.template_nodes = template_nodes
self.queryset_var = queryset_var
self.order_var = order_var

def _render_node(self, context, node):
bits = []
context.push()

children = node.get_children()

if children and self.order_var is not None:
children = children.order_by(self.order_var)

for child in children:
bits.append(self._render_node(context, child))
context['node'] = node
context['children'] = mark_safe(''.join(bits))
rendered = self.template_nodes.render(context)
context.pop()
return rendered

def render(self, context):
queryset = self.queryset_var.resolve(context)
roots = cache_tree_children(queryset)
bits = [self._render_node(context, node) for node in roots]
return ''.join(bits)


@register.tag
def recursetree(parser, token):
bits = token.contents.split()
if len(bits) < 2:
raise template.TemplateSyntaxError(_('%s tag requires a queryset') % bits[0])

queryset_var = template.Variable(bits[1])

if len(bits) == 3:
order_var = bits[2]
else:
order_var = None

template_nodes = parser.parse(('endrecursetree',))
parser.delete_first_token()

return RecurseTreeNode(template_nodes, queryset_var, order_var)

关于python - django-mptt 中的动态顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31341468/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com