ビュー内のPythonコードと同等のオブジェクトのセットを取得するには、djangoテンプレート内からフィルター処理されたクエリを実行する必要があります。
queryset = Modelclass.objects.filter(somekey=foo)
私のテンプレートでやりたい
{% for object in data.somekey_set.FILTER %}
でも、FILTERの書き方がわからないようです。
回答:
これは仕様によるものです。Djangoフレームワークの作成者は、プレゼンテーションコードをデータロジックから厳密に分離することを意図していました。モデルのフィルタリングはデータロジックであり、HTMLの出力はプレゼンテーションロジックです。
したがって、いくつかのオプションがあります。最も簡単なのは、フィルタリングを実行してから、結果をに渡すことrender_to_response
です。または、モデルにメソッドを記述して、と言うことができます{% for object in data.filtered_set %}
。最後に、独自のテンプレートタグを作成することもできますが、この特定のケースでは、それをお勧めしません。
次のようなテンプレートタグを追加するだけです。
@register.filter
def in_category(things, category):
return things.filter(category=category)
それから私はすることができます:
{% for category in categories %}
{% for thing in things|in_category:category %}
{{ thing }}
{% endfor %}
{% endfor %}
'for' statements should use the format 'for x in y': for p in r | people_in_roll_department:d
。何か案は?
私は定期的にこの問題に遭遇し、しばしば「メソッドの追加」ソリューションを使用します。ただし、「メソッドを追加する」または「ビューで計算する」が機能しない(またはうまく機能しない)場合は間違いなくあります。たとえば、テンプレートフラグメントをキャッシュしていて、それを生成するために重要なDB計算が必要な場合です。必要がない限りDB作業を行いたくはありませんが、テンプレートロジックを深く理解するまで、必要かどうかはわかりません。
他のいくつかの可能な解決策:
http://www.djangosnippets.org/snippets/9/にある{%expr <expression> as <var_name>%}テンプレートタグを使用します。この式は、テンプレートのコンテキストをローカルスコープとする合法的なPython式です。
テンプレートプロセッサを変更します。Jinja2(http://jinja.pocoo.org/2/)の構文は、Djangoテンプレート言語とほぼ同じですが、Pythonの全機能を利用できます。また、より高速です。これを大規模に行うことも、作業中のテンプレートに使用を制限することもできますが、デザイナーが管理するページにはDjangoの「より安全な」テンプレートを使用します。
もう1つのオプションは、常に適用するフィルターがある場合、問題のモデルにカスタムマネージャーを追加して、返される結果に常にフィルターを適用することです。
この良い例はEvent
モデルです。モデルに対して行うクエリの90%で、次のようなものが必要になりEvent.objects.filter(date__gte=now)
ます。つまり、通常はEvents
それに関心があります。これは次のようになります。
class EventManager(models.Manager):
def get_query_set(self):
now = datetime.now()
return super(EventManager,self).get_query_set().filter(date__gte=now)
そしてモデルでは:
class Event(models.Model):
...
objects = EventManager()
ただし、これもEvent
モデルで実行されるすべてのデフォルトクエリに対して同じフィルタを適用するため、上記の手法の一部はそれほど柔軟ではありません。
これは、割り当てタグで解決できます。
from django import template
register = template.Library()
@register.assignment_tag
def query(qs, **kwargs):
""" template tag which allows queryset filtering. Usage:
{% query books author=author as mybooks %}
{% for book in mybooks %}
...
{% endfor %}
"""
return qs.filter(**kwargs)
2020年に答えを探している人のために。これは私のために働いた。
ビュー内:
class InstancesView(generic.ListView):
model = AlarmInstance
context_object_name = 'settings_context'
queryset = Group.objects.all()
template_name = 'insta_list.html'
@register.filter
def filter_unknown(self, aVal):
result = aVal.filter(is_known=False)
return result
@register.filter
def filter_known(self, aVal):
result = aVal.filter(is_known=True)
return result
テンプレート内:
{% for instance in alarm.qar_alarm_instances|filter_unknown:alarm.qar_alarm_instances %}
擬似コードの場合:
For each in model.child_object|view_filter:filter_arg
お役に立てば幸いです。