2011-12-15 2 views
2

게시물 목록을 표시하기 위해 장고를 사용하고 있습니다. 각 게시물에는 'is_public'필드가 있으므로 한 게시물의 'is_public'이 False이면 사용자에게 표시하면 안됩니다. 또한 한 페이지에 고정 된 수의 게시물을 표시하려고하지만보기에 따라이 숫자가 달라질 수 있습니다.Django 템플릿의 루프 : 루프 반복자를 제어하는 ​​방법?

몇 가지보기가 동일한 템플릿을 사용하므로 템플릿에서 쿼리 세트를 자르기로 결정하여보기에서 생성하면 많은 반복 코드가 발생합니다. 파이썬으로 작성된 경우

, 그것은 다음과 같아야합니다

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

을 장고 템플릿으로 지원하지 않습니다 루프와 루프 제어하기 어려운 것 같다 동안이를 달성하는 방법은 무엇입니까? 아니면 다른 방법으로해야합니까? (하나의 아이디어는 루핑하기 전에 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

템플릿은 여러 뷰에서 사용되므로이 뷰에서 반복해서 반복하지는 않을 것입니다. 또한, 원래 관리자가 아닌 사람들에게 보여주기위한 아이디어가있었습니다. 그래서 저는 전에 queryset을 자르고 싶지 않았습니다. 너무 복잡해서 결코 신경 쓸 필요가 없습니다. –

답변

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을 사용하여 대부분 자동화 할 수 있습니다.