2017-06-08 23 views
0

我想創建一個博客應用程序,其中有帖子,每個帖子都有標題,日期,鏈接和標籤。如何迭代django-jinja項目中的ManyToManyField?

這是我的models.py

# models.py 
from django.db import models 

class Tag(models.Model): 
    name = models.CharField(max_length=20) 

    def __str__(self): 
     return self.name 

    class Meta: 
     ordering = ('name',) 

class Post(models.Model): 
    title = models.CharField(max_length=300) 
    date = models.DateTimeField() 
    link = models.URLField() 
    tags = models.ManyToManyField(Tag) 

    def __str__(self): 
     return self.title 

    @property 
    def tags_name(self): 
     return [x.name for x in self.tags] 

    class Meta: 
     ordering = ('date',) 

這是我的views.py

# views.py 
from django.conf.urls import url, include 
from django.views.generic import ListView 
from blog.models import Post 

urlpatterns = [ 
    url(r'^$', ListView.as_view(queryset=Post.objects.all().order_by("-date"), template_name="blog/blog_list.html")), 
] 

這是我blog_list.html

<!-- blog_list.html --> 
{% extends "mysite/layout.html" %} 

{% block content %} 
    <h1>my blog posts</h1> 
    <ul> 
    {% for post in object_list %} 
     <li><span class="title"><a href="{{ post.link }}">{{ post.title }}</a></span></li> 
     <p>{{ post.date|date:"d-m-Y" }}</p> 
    {% endfor %} 
    </ul> 
{% endblock %} 

{% block sidebar %} 
    <h4 id="sidenav">tags</h4> 
    {% for post in object_list %} 
    <ul> 
     <!-- I want to show the tags here --> 
    </ul> 
    {% endfor %} 
{% endblock %} 

在blog_list.html,我我展示了所有帖子的詳細信息,並在側邊欄上顯示了所有可用博客帖子中的所有標籤。由於post.tags是ManyToManyField,我怎樣才能遍歷它呢?

+0

您是否嘗試過''{%for post.tags.all()%}''''?在for循環中,你應該能夠以'''{{tag}}''的形式訪問標籤。 –

+1

@ISOmetric我認爲你的意思是'{%for post.tags.all%中的標記} {{tag}} {%endfor%}''()'不允許! – hansTheFranz

+0

@hansTheFranz是的,我相信你是對的,我的錯誤。 –

回答

0

你想用.all在模板中獲得的關係的所有元素:

{% for tag in post.tags.all %} 
    {{ tag }} 
{% endfor %} 

感謝@hansTheFranz糾正我的支架問題。

關於不重複標籤,在當前情況下,這將非常困難。您可能需要考慮在您的視圖中獲取帖子並在其中提取標籤,在那裏您可以更自由地檢查重複項。事情是這樣的:

def tags(request): 
    posts = Post.objects.all() 
    tag_list = [] 
    for post in posts: 
     tags = post.tags.all() 
     for tag in tag: 
      if not (tag in tag_list): 
       tag_list.append(tag) 
    context_dict = { "tags": tag_list, "posts": posts } 
    return render(request, 'blog/blog_list.html', context_dict) 

urlpatterns = [ 
    url(r'^$', tags, name="tags"), 
] 

,然後改變你的模板更喜歡:

{% block sidebar %} 
    <h4 id="sidenav">tags</h4> 
    <ul> 
     {% for tag in tags %} 
     <li>{{ tag }}</li> 
     {% endfor %} 
    </ul> 
{% endblock %} 

此外,而不是引用object_list您現在可以通過引用posts訪問文章列表,因爲我們已經定義我們的上下文字典中的帖子列表正在傳遞給模板。

恐怕我沒有測試過它,它可能不是非常有效,但粗略地說它應該工作。我大學的一位講師寫了這本書:http://www.tangowithdjango.com/book17/,鼓勵更多的寫作風格,我已經做了:與網址分開。如果我所做的任何事情似乎都不清楚或相反,你可能想看看這本書,看看有沒有什麼更合理的。