django-mpttの動的順序

Peterek

コメントアプリケーションに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

コメントツリーを辛さや作成日で並べ替えることができるようにしたいと思います。order_insertion_byビューからフィールドを編集して、2種類の並べ替え(日付別、辛さ別)を生成することはできますか?ご協力いただきありがとうございます。

biodiv

Modified Preorder Tree Traversal(MPTT)(左用いたものクエリでツリー構造を取得するための方法であるlftMPTTで)、右(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、親要素の子(子孫ではない)を表す兄弟の順序を指定します。次の2つの異なる注文をしたい、場合lftrgtaswell変更する必要がありますので、それは第二の木です。これはmpttには含まれていません。

あなたはまだすることができます

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

しかし、ツリー構造は失われます。一般に、ツリー構造を維持し、ツリー全体を他の何か(たとえば、暑さ)で順序付けることはできません。次のものがあると想像してください。

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

その結果、

Comment2
Comment3
Comment1

注文されていますComment2が、に添付されていませんComment1order_insertion_by兄弟レベルベースで定義されている以外のものを使用してソートする場合は、次のようにします。

Comment3
Comment1
    Comment2

要素{% recursetree objects -hotness %}を繰り返して再ソートしchildren、新しいツリーを返すような新しいテンプレートタグを作成できる場合があります。それでも1つのデータベースクエリですが、パフォーマンスへの影響を見積もることはできません。

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)

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

TOP 一覧

  1. 1

    Unity:未知のスクリプトをGameObject(カスタムエディター)に動的にアタッチする方法

  2. 2

    セレンのモデルダイアログからテキストを抽出するにはどうすればよいですか?

  3. 3

    Ansibleで複数行のシェルスクリプトを実行する方法

  4. 4

    tkinterウィンドウを閉じてもPythonプログラムが終了しない

  5. 5

    Crashlytics:コンパイラー生成とはどういう意味ですか?

  6. 6

    GoDaddyでのCKEditorとKCfinderの画像プレビュー

  7. 7

    Windows 10 Pro 1709を1803、1809、または1903に更新しますか?

  8. 8

    Chromeウェブアプリのウェブビューの高さの問題

  9. 9

    モーダルダイアログを自動的に閉じる-サーバーコードが完了したら、Googleスプレッドシートのダイアログを閉じます

  10. 10

    Windows 10の起動時間:以前は20秒でしたが、現在は6〜8倍になっています

  11. 11

    Reactでclsxを使用する方法

  12. 12

    ファイル内の2つのマーカー間のテキストを、別のファイルのテキストのセクションに置き換えるにはどうすればよいですか?

  13. 13

    MLでのデータ前処理の背後にある直感

  14. 14

    グラフからテーブルに条件付き書式を適用するにはどうすればよいですか?

  15. 15

    Pythonを使用して同じ列の同じ値の間の時差を取得する方法

  16. 16

    mutate_allとifelseを組み合わせるにはどうすればよいですか

  17. 17

    ネットワークグラフで、ネットワークコンポーネントにカーソルを合わせたときに、それらを強調表示するにはどうすればよいですか?

  18. 18

    テキストフィールドの値に基づいて UIslider を移動します

  19. 19

    BLOBストレージからデータを読み取り、Azure関数アプリを使用してデータにアクセスする方法

  20. 20

    PowerShellの分割ファイルへのヘッダーの追加

  21. 21

    ソートされた検索、ターゲット値未満の数をカウント

ホットタグ

アーカイブ