1. ホーム
  2. python

[解決済み] Django テンプレートで関連する項目を並べ替える

2023-01-17 13:09:56

質問

DJangoテンプレートで、関連するアイテムのセットをソートすることは可能でしょうか?

つまり:このコード(わかりやすくするためにHTMLタグは省略しています)。

{% for event in eventsCollection %}
   {{ event.location }}
   {% for attendee in event.attendee_set.all %}
     {{ attendee.first_name }} {{ attendee.last_name }}
   {% endfor %}
 {% endfor %}

表示 ほとんど はまさに私が欲しいものです。 私が変更したい唯一のものは、出席者のリストを姓の順に並べることです。 私はこのようなことを言うことを試みました。

{% for event in events %}
   {{ event.location }}
   {% for attendee in event.attendee_set.order_by__last_name %}
     {{ attendee.first_name }} {{ attendee.last_name }}
   {% endfor %}
 {% endfor %}

残念ながら、上記の構文はうまくいきません(空のリストを生成します)。

もちろん、私のビューで並べ替えられた出席者リストのある種の配列を生成することはできますが、それは醜くて壊れやすい (そして、醜いと言いましたっけ) 解決策です。

言うまでもなく、とにかく言いますが、私はオンラインドキュメントを熟読し、Stack Overflow と django-user のアーカイブを検索しましたが、役に立つものは見つかりませんでした (ああ、クエリーセットが辞書であれば、dictsort は仕事をしますが、そうではなく、そうもいきません)。

==============================================

タウマスの回答を受け、考えを追加するために編集 Tawmasさんの回答を受け、追記しました。


Tawmasは、私が提示したとおりの問題に対処してくれました。 その結果、私は他の状況でも使える有用なテクニックを学びました。

Tom の回答は、私が OP ですでに言及し、醜いとして暫定的に拒否していたアプローチを提案しました。

醜い」というのは直感的な反応であり、何が問題なのかを明らかにしたかったのです。 そうすることで、醜いアプローチである理由は、レンダリングするテンプレートにクエリ セットを渡すという考えにこだわっていたためであることに気づきました。 その要件を緩和すれば、醜くないアプローチで動作するはずです。

まだ試していませんが、クエリセットを渡すのではなく、ビューコードがクエリセットを通して反復し、イベントのリストを生成し、各イベントを対応する出席者のクエリセットで装飾するとします。 WAS でソート(またはフィルタリング)されます。 このようなものです。

eventCollection = []   
events = Event.object.[filtered and sorted to taste]
for event in events:
   event.attendee_list = event.attendee_set.[filtered and sorted to taste]
   eventCollection.append(event)

これでテンプレートはこうなります。

{% for event in events %}
   {{ event.location }}
   {% for attendee in event.attendee_list %}
     {{ attendee.first_name }} {{ attendee.last_name }}
   {% endfor %}
 {% endfor %}

欠点は、ビューが一度にすべてのイベントを実現しなければならないことで、大量のイベントがある場合には問題になります。 もちろん、ページ分割を追加することもできますが、それはビューをかなり複雑にしてしまいます。

良い点は、quot; prepare the data to be displayed" コードはビューにあり、テンプレートが表示のためにビューによって提供されるデータのフォーマットに集中できるようにすることです。これは正しく、適切なことです。

そこで、私の計画では、大きなテーブルには Tawmas のテクニックを使用し、小さなテーブルには上記のテクニックを使用することにします。 大小の定義は読者にお任せします(笑)。

どう解決する?

このように、attendeeモデルで順序を指定する必要があります。例えば(モデルクラスがAttendeeという名前だと仮定して)。

class Attendee(models.Model):
    class Meta:
        ordering = ['last_name']

参照 マニュアル を参照してください。

EDIT . 別の解決策は、テンプレートからアクセスできるように、イベントモデルにプロパティを追加することです。

class Event(models.Model):
# ...
@property
def sorted_attendee_set(self):
    return self.attendee_set.order_by('last_name')

必要に応じて、さらにこれらを定義することができます...