1つのクエリセットを2つのdiv列にレンダリングします(djangoテンプレート)
-
05-07-2019 - |
質問
クエリセットの列挙を2つの div
列にレンダリングする良い方法はありますか?
960グリッドを使用すると、次の効果が得られます...
<div class="container_16">
<div class="grid_8 alpha"></div>
<div class="grid_8 omega"></div>
</div>
Djangoでは、1つのモデルで、列挙されたコンテンツを両方の列でレンダリングする必要があります。とりあえず、ビューでQuerySetを2つの半分に分割し、それぞれの半分をそれぞれの列にレンダリングするsomeいコードをいくつか持っています。
できればテンプレートレンダリングシステムのみを使用して、これを行うためのより良い方法が必要ですか?
参考までに、以下に「動作」を示します。現時点では:
views.py
@render_to('template.html')
def main_athletics_page(request, *args, **kwargs):
sports = Sport.objects.all()
half = sports.count() / 2
return { 'sports_1' : sports[0:half], 'sports_2' : sports[half:] }
template.html
<div class="grid_8 alpha">
{% for sport in sports_1 %}
<!-- Blah blah -->
{% endfor %}
</div>
<div class="grid_8 omega">
{% for sport in sports_2 %}
<!-- Blah blah -->
{% endfor %}
</div>
解決
Djangoフィルターを使用することをお勧めします。
Djangoスニペットはパーティションテンプレートフィルターを提供します。これは次のように使用できます。
{% load listutil %}
<div class="grid_8 alpha">
{% for sport in sports|partition:"2"|first %}
<!-- Blah Blah -->
{% endfor %}
</div>
<div class="grid_8 omega">
{% for sport in sports|partition:"2"|last %}
<!-- Blah Blah -->
{% endfor %}
</div>
他のヒント
- これは、ビューではなくレンダリングシステムのタスクです。ビューには、テンプレートに2、3、または4列を表示するかどうかがわからないようにしてください。
- 常にデフォルトのDjangoタグを使用することをお勧めします。
デフォルトのDjangoテンプレートタグ cycle
を使用:
<table>
{% for item in items %}
{% cycle 'row' '' as row silent %}
{% if row %}<tr>{% endif %}
<td>
{{ item }}
</td>
{% if not row %}</tr>{% endif %}
{% endfor %}
</table>
リスト[1 2 3 4 5 6]として表示されます
1 2
3 4
5 6
ところで、Jinja2テンプレートエンジンには、トリックを行う batch
および slice
フィルターがあります。私はjinja2に切り替えましたが、「質の悪いdjangoタグとフィルターを使用してxを表示する方法」という問題はなくなりました
クエリを分割するには、独自のテンプレートタグを作成する必要があると思います。私は次のようなことをします。
from django.template import Library, Node, TemplateSyntaxError
from restaurants.forms import MenuItemForm
class Split(Node):
def __init__(self, queryset, split_count=2, basename=None):
self.queryset_name = queryset
self.split_count = split_count
self.basename = basename if basename else queryset
def render(self, context):
qs = context[self.queryset_name]
qs_break = len(qs)/self.split_count
for x in xrange(0, self.split_count-1):
context["%s_%i"%(self.basename, x+1)] = qs[qs_break*x:qs_break*(x+1)]
context["%s_%i"%(self.basename, x+2)] = qs[qs_break*x+1:]
return ''
def split(parser, token):
"""
Call from template will be
{% split <queryset> on <count> as <name> %}
"""
tokens = token.split_contents()
if len(tokens) > 6:
raise TemplateSyntaxError("Too many Tokens")
#Do various tests to make sure it's right.
return Split(tokens[1], tokens[3], tokens[5])
split = register.tag(split)
このコードは実際にはテストしていないため、見事に失敗する可能性がありますが、ビューからそのようなものを取得するための正しい方向を示す必要があります。
これは、ブートストラップを使用し、Djangoフィルターを必要としない簡単なソリューションです
<div class="row">
{% for sport in sports %}
<div class="col-md-6">
<!-- Blah Blah -->
</div>
{% endfor %}
</div>
所属していません StackOverflow