2011-12-15 11 views
2

私はDjangoを使って投稿のリストを表示しています。各投稿には 'is_public'フィールドがあります。したがって、1つの投稿の 'is_public'がFalseに等しい場合、その投稿をユーザーに表示すべきではありません。また、あるページに一定数の投稿を表示したいが、この数はビューによって変わることがある。Djangoテンプレートのループ:ループ反復子を制御する方法は?

テンプレート内のクエリーセットを切り抜くことを決めました。いくつかのビューが同じテンプレートを使用しているため、ビュー内で生成すると繰り返しコードがたくさんあります。 Pythonで書かれている場合

、それは次のようになります。

i=number_of_posts_to_show_in_one_page 
while i: 
    if qs[i].is_public == True: 
    #show qs[i] to the page 
    i-- 

をDjangoテンプレートとしてサポートしていないループとforループの制御が難しいようですが、これを達成する方法はありますか?または別の方法でそれを行う必要がありますか(1つのアイデアはループの前にqを切り抜くことです)ありがとう!

アップデート:私は前処理に、このテンプレートタグクエリセット書いた

:テンプレートにforループを使用する前に

@register.simple_tag(takes_context=True) 
    def pre_process_list(context,list,numbers): 
     #if not user.has_perm('admin'): 
     context['result_list']=list.filter(is_public=True, is_removed=False)[0:numbers] 
     #else: 
     #context['result_list']=list[0:numbers] 
     return '' 

を、私はこのtemplageにクエリセットを渡しますタグを使用し、簡単なforループを使用してその結果を表示します。

未公開の投稿を管理者に公開したい場合(まだ未定)、コメントしたようなロジックで書くことができ、テンプレートのスタイルを違うものにすることができます。

+5

ビュー内に適切なQuerySetを作成することをお勧めします。そのような論理はそこに属し、より管理しやすくなります。 – LaundroMat

+0

テンプレートはいくつかのビューで使用されるので、これらのビューで何度も何度も繰り返すことはありません。また、もともと私は非公開のものを管理者に見せるというアイデアを持っていました。そのため私は手元にあるクエリセットを作ってみたくなかったのです。それは複雑すぎるかもしれないので、決して気にしないでください –

答えて

3
{% for post in posts %} 
    {% if post.is_public %} 
    {{ post }} 
    {% endif %} 
{% endfor %} 

これはmanagerの完璧な使用例ですが、

パブリック投稿をフィルタリングするシンプルな管理者を作成できます。

class PublicPostManager(models.Manager): 
    def get_query_set(self): 
     return super(PublicPostManager, self).get_query_set().filter(is_public=True) 

次に、あなたのPostクラスにそれを追加します。

class Post(models.Model): 
    ... 
    public = PublicPostManager() 

次に、あなたがあなたのループをpost.public.all()public_postsとしてあなたのテンプレートを渡し、簡素化することができます:

{% for post in public_posts %} 
    {{ post }} 
{% endfor %} 
2

@arieが持っていますマネージャーとの良好なアプローチですが、マネージャーを書くことなく簡単に同じことができます:

# View 
posts = Post.objects.filter(is_public=True) # or use the manager 
# Now, you can either limit the number of posts you send 
# posts = posts[:5] (only show five in the view) 
return render_to_response('foo.html',{'posts':posts}) 

# Template 
# Or you can do the limits in your template itself: 
{% for post in posts|slice:":5" %} 
    {{ post }} 
{% endfor %} 

詳細については、slice filterを参照してください。

しかし、これは一般的な操作であるため、django 1.3ではclass based viewsを使用してほとんどの作業を自動化できます。