云标签比较简单,我们就先来说云标签把
首先我们得先修改models,增加一个Tag表,然后以多对多的方式关联Article,也就是说一篇文章会有多个标签,一个标签下会有多篇文章。
class Tag(models.Model): name = models.CharField('标签名', max_length=20) created_time = models.DateTimeField('创建时间', auto_now_add=True) last_modified_time = models.DateTimeField('修改时间', auto_now=True) def __unicode__(self): return self.name
然后在Article表中增加一个多对多的键
category = models.ForeignKey('Category', verbose_name='分类', null=True, default='其他', on_delete=models.SET_NULL) tag = models.ManyToManyField('Tag', verbose_name='标签集合', blank=True)
接着我们修改视图,新增一个tagview视图,大家可以看出和index视图很像,因为我们直接用的index.html,只是第一个文章列表articlelist不一样
def tag_view(request, tag_id): article_list = Article.objects.filter(tag__id=tag_id) category_list = Category.objects.all().order_by('name') tag_list = Tag.objects.all().order_by('name') for tag in tag_list: tag.length = len(Article.objects.filter(tag__id=tag.id)) return render(request, 'article/index.html', {'article_list': article_list, 'category_list': category_list, 'tag_list': tag_list})
当然index视图也要改变
def index(request): article_list = Article.objects.all() category_list = Category.objects.all().order_by('name') tag_list = Tag.objects.all().order_by('name') for tag in tag_list: tag.length = len(Article.objects.filter(tag__id=tag.id)) return render(request, 'article/index.html', {'article_list': article_list, 'category_list': category_list, 'tag_list': tag_list})
其实和上面差别不大。。。
接下来就是修改模板文件index.html了
<div class="panel panel-default"> <div class="panel-heading">标签</div> <div class="panel-body"> {% for tag in tag_list %} <a href="{% url 'tag' tag.id %}"></a> <a href="{% url 'tag' tag.id %}" class="btn btn-info tag_list">{{ tag.name }}<span class="badge">{{ tag.length }}</span></a> {% endfor %} </div> </div>{% endblock %}
我们新增加一个面板用来显示我们的云标签
最后增加一个url就可以啦~
url(r'^tag/(?P<tag_id>\d+)$', tag_view, name='tag'),
文章归类
下来就是按时间对文章进行归类
在具体实施之前得介绍几个概念,首先时datetimes函数,这个函数可以选出数据库中某个model对应的全部已去重的时间,并且可以任意指定精度。我们可以精确到年,月,或者日等等
date_list = Article.objects.datetimes('create_time', 'month', order='DESC')
create_time是Article中文章的发表时间,month表示精确到月,DESC表示降序排列,默认时升序 还有个东东就是管理器(Manager)。是django中很重要的一坨
管理器是django的模型进行数据库查询操作的接口,Django应用的每个模块都拥有至少一个管理器,默认情况下,django为每个模型类增加一个名为objects的管理器,我们可以在模型中使用自定义的管理器,方法时继承Manager基类并实例化自定义的管理器。 这里还用到python的一个模块,collections模块中有一个defaultdice()经常被用到, 这里的defaultdict(functionfactory)构建的是一个类似dictionary的对象,其中keys的值,自行确定赋值,但是values的类型,是functionfactory的类实例,而且具有默认值。比如default(int)则创建一个类似dictionary对象,里面任何的values都是int的实例,而且就算是一个不存在的key, d[key] 也有一个默认值,这个默认值是int()的默认值0.如果不是很明白就给大家一个链接defaultdice
首先我们得扩展Manager类,也就是继承并加入新的方法
class ArticleManager(models.Manager):#放在所有models前面 def archive(self): date_list = Article.objects.datetimes('create_time', 'month', order='DESC') # 获取到降序排列的精确到月份且已去重的文章发表时间列表 # 并把列表转为一个字典,字典的键为年份,值为该年份下对应的月份列表 date_dict = defaultdict(list) for d in date_list: date_dict[d.year].append(d.month) # 模板不支持defaultdict,因此我们把它转换成一个二级列表,由于字典转换后无序,因此重新降序排序 return sorted(date_dict.items(), reverse=True)
自定义了Manger后需要在model中显示的指示它:
article/models.pyclass Article(models.model): ... # 仍然使用默认的 objects 作为 manager 的名字 objects = ArticleManager() ...
现在我们在视图中就可以调用了
def index(request): article_list = Article.objects.all() category_list = Category.objects.all().order_by('name') tag_list = Tag.objects.all().order_by('name') date_archive = Article.objects.archive() for tag in tag_list: tag.length = len(Article.objects.filter(tag__id=tag.id)) return render(request, 'article/index.html', {'article_list': article_list, 'category_list': category_list, 'tag_list': tag_list, 'date_archive': date_archive})
然后我们在模板中把它渲染出来
{% for year,month_list in date_archive %} `year` 年 {% for month in month_list %} `month`月 {% endfor %} {% endfor %}
当然,这只是显示出来时间的列表,我们是想通过点击时间,然后列出这个时间段下的所有文章。我们来开始实现它! 首先我们先增加一个视图,如下:
def archive_view(request, year, month): article_list = Article.objects.filter(create_time__year=int(year), create_time__month=int(month)) category_list = Category.objects.all().order_by('name') tag_list = Tag.objects.all().order_by('name') date_archive = Article.objects.archive() for tag in tag_list: tag.length = len(Article.objects.filter(tag__id=tag.id)) return render(request, 'article/index.html', {'article_list': article_list, 'category_list': category_list, 'tag_list': tag_list, 'date_archive': date_archive})
接下来我们新增一个url咯
url(r'^archive/(?P<year>\d+)/(?P<month>\d+)/$', archive_view, name='archive'),
然后我们在index.html中从新渲染~
<div class="panel panel-default"> <div class="panel-heading">标签</div> <div class="panel-body"> {% for year,month_list in date_archive %} `year` 年 {% for month in month_list %} <a href="{% url 'archive' year month %}"><p>{{ month }} 月</p></a> {% endfor %} {% endfor %} </div></div>
不懂地方,问博主哈~~~ 博主邮件:690347460@qq.com 本系列文章,参考自:
转载于:https://blog.51cto.com/xiaofengfeng/1885775