真是活久见,玩了两天DES,今天想把详情页不能写中文的问题解决~~把detail.html代码里的首页改成中文,它喵的居然直接就好了。既然这样,我只能继续了。
前端可能要留在最后,目前逐渐扩展功能,这次把标签和分类整进去:
优快云中,分类是作者此分类下的文章汇总,标签是全站有此标签的文章汇总。我搭的是个人博客,自然两者都是作者文章汇总。
一、分类和标签的模型
每篇文章只有一个分类,一个分类下有很多文章,所以文章和分类是多对一关系;每篇文章可以有多个标签,因此文章和标签是多对多关系。分析他们关系是因为在编写模型中要用。
这是套路了,博客毕竟是数据库驱动的WEB,任何新东西都应该是从数据库开始的。
分类的模型之前写过,只有简单的几行代码:
#创建分类模型
class Category(models.Model):
category = models.CharField('分类',max_length=10)
def __str__(self):
return self.category
同理,标签的模型抄写之:
#创建标签模型
class Tag(models.Model):
tag = models.CharField('标签',max_length=15)
def __str__(self):
return self.tag
前面分析的多对多关系要用在Article模型中,把文章和标签的关系建立起来:
# models.py
class Article(models.Model):
……
tag = models.ManyToManyField('Tag',verbose_name='标签',blank=True)
……
模型就这么简单,记得每次更改了数据库都要做的事:
D:\myblog>python manage.py makemigrations blog
D:\myblog>python manage.py migrate
ForeignKey和ManyToManyField的更多内容:官方文档或中文文档
因为涉及一个新的模型,要把它激活才可以在后台操作。
# admin.py
from django.contrib import admin
from .models import Article,Category,**Tag**
admin.site.register(Article)
admin.site.register(Category)
**admin.site.register(Tag)**
现在我重启服务器,进入后台。
Tag已经出现,可以添加一些标签。
二、分类和标签的视图
简单改了一下首页的html:
# index.html
<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<head><title>首页</title></head>
<body>
<h3>分类<h3>
{% for category in category_list%}
<a href="{% url 'blog:category' category.pk %}">{{category.category}}</a><br>
{% endfor %}
<h3>标签</h3>
{% for tag in tag_list%}
<a href="{% url 'blog:tag' tag.pk %}">{{tag.tag}}</a><br>
{% endfor %}
<h3>文章列表</h3>
{% for article in article_list%}
<a href="{% url 'blog:detail' article.pk %}">{{article.title}}</a><br>
{% endfor %}
</body>
</html>
我的愿望是美好的,可惜现实是残酷的,此时的首页是这样的:
分类和标签列表并没有显示,因为我的首页视图里并没有对他们的操作,现在重写一个方法,返回分类和标签的列表。
# views.py
from .models import Article,**Category,Tag**
class IndexView(ListView):
……
#重写ListView下的get_context_data()方法,返回分类和标签列表
def get_context_data(self,**kwargs):
#category_list与html中一致,category与Category模型中的category一致
kwargs['category_list'] = Category.objects.all().order_by('category')
kwargs['tag_list'] = Tag.objects.all().order_by('tag')
return super(IndexView,self).get_context_data(**kwargs)
一切正常的话,首页应该OK了。而我刷新首页,得到的却是这个:
看到这图我就崩溃了,因为快到晚饭时间了,而django让我把分类和标签的url和view都搞定,才给显示首页。
按照习惯,先写URLconf,都照article的改写。
# blog/urls.py
urlpatterns = [
……
url(r'^category/(?P<category_id>\d+)$',views.CategoryView.as_view(),name='category'),
url(r'^tag/(?P<tag_id>\d+)$',views.TagView.as_view(),name='tag'),
]
编写分类和标签视图,因为他们的模式都是文章列表,和首页挺像,也可以模仿着改。
# views.py
class CategoryView(ListView):
template_name = 'blog/index.html' #和首页一样
context_object_name = 'article_list' #要的就是文章列表,也是一样
#重写get_queryset方法,从已发布的文章中按分类筛选
def get_queryset(self):
article_list = Article.objects.filter(category=self.kwargs['category_id'],status='published')
return article_list
#重写,返回分类和标签列表
def get_context_data(self,**kwargs):
kwargs['category_list'] = Category.objects.all().order_by('category')
kwargs['tag_list'] = Tag.objects.all().order_by('tag')
return super(CategoryView,self).get_context_data(**kwargs)
#和CategoryView完全一样
class TagView(ListView):
template_name = 'blog/index.html' #和首页一样
context_object_name = 'article_list' #要的就是文章列表,也是一样
#重写get_queryset方法,从已发布的文章中按标签筛选
def get_queryset(self):
article_list = Article.objects.filter(tag=self.kwargs['tag_id'],status='published')
return article_list
#重写,返回分类和标签列表
def get_context_data(self,**kwargs):
kwargs['category_list'] = Category.objects.all().order_by('category')
kwargs['tag_list'] = Tag.objects.all().order_by('tag')
return super(TagView,self).get_context_data(**kwargs)
大功告成,请看效果:
写完我自己有个疑问:这分类和标签简直一模一样,为什么要分成2个功能?
开饭前茅塞顿开!分类是多对一,标签是多对多,就冲这一点,我就要分开写啊~~现在看首页貌似一样,未来专攻前端时自然会把他俩区分开的。
Done!下次添加评论。