PyxYuYu/MyBlog

Django学习记录(十七):Django by example -- Blog(十三)

PyxYuYu opened this issue · 0 comments

Learn from yesterday, live for today, look to tomorrow.

0x01 Django

  • Build a Blog Application
    • Adding tagging functionality
    • 通过导入一个第三方的标签应用来创建一个标签 posts 的方法
    • django-taggit 这个第三方应用提供了 Tag 模型和 manager 来简单的导入标签给任何模型
    • 安装 pip install django-taggit==0.21.3 或者用 PyCharm 的管理工具安装
    • settings.py 中将 django-taggit 添加到 INSTALLED_APPS
       INSTALLED_APPS = (
           # ...
           'blog',
           'taggit',
       )
    • models.py 中添加 TaggableManager 标签管理器到 Post 模型中
       from taggit.managers import TaggableManager
       
       class Post(models.Model):
           # ...
           tags = TaggableManager()
    • 标签管理器允许我们对标签进行增加、检索和移动
    • 进行数据迁移,同步到数据库
       python manage.py makemigrations blog
       python manage.py migrate
    • 同步之后,就可以使用 django-taggit,打开 shell,看看标签管理器的用法
      • python manage.py shell
      • 检索 id=1post
         >>> from blog.models import Post
         >>>> post = Post.objects.get(id=1)
      • 之后就可以给这个 post 增加一些标签,也可以用 tags.all() 来验证是否增加成功
         >>> post.tags.add('aaa', 'bbb', 'ccc')
         >>> post.tags.all()
         [<Tag: aaa>, <Tag: bbb>, <Tag: ccc>]
      • 利用 tags.remove(aaa) 也可以删除指定标签
         >>> post.tags.remove('ccc')
         >>> post.tags.all()
         [<Tag: aaa>, <Tag: bbb>]
      • 运行 python manage.py runserver 后,可以在 http://localhost:8000/admin/taggit/tag 页面查看到标签列表,可以看到之前创建的3个标签,被移除的 ccc 也在,只是将 ccc 移除到 post id=1
      • post 编辑页面下面也会出现一个标签字段用于添加标签
    • 在模板上面显示标签,编辑 blog/post/list.html ,在 post title 后添加
       <p class="tags">Tags: {{ post.tags.all|join:", " }}</p>
    • join 这个模板过滤器 {{ list|join:", " }} 用指定分隔符连接列表(这里用逗号连接)
    • 接下来需要实现一个功能:根据指定的标签列出这些标签所标的 posts
      • 编辑 blog/views.py 导入 Tag 模型
         from taggit.models import Tag
         
         def post_list(request, tag_slug=None):
             object_list = Post.published.all()
         	tag = None
         	
         	if tag_slug:
         	    tag = get_object_or_404(Tag, slug=tag_slug)
         		object_list = object_list.filter(tags__in=[tag])
         		# ...
         	
         	return render(request, 'blog/post/list.html', {'page': page, 'posts': posts,
         	                                               'tag': tag})
      • post_list 需要一个 tag_slug参数,默认是 None,从 URL 中获取
      • 在函数内建立了一个查询集,检索所有的公开 posts ,如果有 tag_slug ,用 get_object_or_404() 获取这个 tag ,然后利用个这个标签过滤获得所需要的 posts,最后在 render() 中添加 tag 传送给模板
      • 因为根据 URL 获取 tag_slug ,所以修改 urls.py,添加
         url(r'^tag/(?P<tag_slug>[-\w]+)/$', views.post_list, name='post_list_by_tag'),
      • 接着需要在模板中进行修改,因为之前用的是 Django 的内置类 ListView 写的 post 列表,所以需要修改 blog/post/list.html
         {% include "pagination.html" with page=posts %}
      • {% for %} 循环上面添加
         {% if tag %}
             <h2>Posts tagged with "{{ tag.name }}"</h2>
         {% endif %}
      • 后面接着显示指定 tag 所过滤出的 posts,修改 <p class="tags">
         <p class="tags">
             Tags:
         	{% for tag in post.tags.all %}
         	    <a href="{% url "blog:post_list_by_tag" tag.slug %}">
         		    {{ tag.name }}
         		</a>
         		{% if not forloop.last %} , {% endif %}
         	{% endfor %}
         </p>
      • forloop.last 是一个布尔值,在最后一次执行循环是被设置为 True,如果不是最后一次都会输出一个逗号,最后一次,就不会继续执行输出逗号