Django搭建博客网站(三)
第三篇主要记录view层的逻辑和template.
Django搭建博客网站(一)
Django搭建博客网站(二)
结构
网站结构决定我要实现什么view.
我主要要用view展示首页,标签页,网站管理员(也就是本人啦)信息页,以及文章详情页.
settings.py
因为到这个阶段需要编写html文件了,但是每一个网页的每一行代码都靠自己去写,各种渲染也靠自己去写的话,太麻烦了,Django提供了html模板功能,可以在settings.py
里面进行配置.
# settings.pyTEMPLATES = [ ???{ ???????‘BACKEND‘: ‘django.template.backends.django.DjangoTemplates‘, ???????‘DIRS‘: [], ???????‘APP_DIRS‘: True, ???????‘OPTIONS‘: { ???????????‘context_processors‘: [ ???????????????‘django.template.context_processors.debug‘, ???????????????‘django.template.context_processors.request‘, ???????????????‘django.contrib.auth.context_processors.auth‘, ???????????????‘django.contrib.messages.context_processors.messages‘, ???????????], ???????}, ???},]
其实在python的众多package里面还有一个叫Jinja2的模块,也是实现html模板功能,不过这里我觉得没必要改成Jinja2,Django本身提供的模板功能已经够用了.
首先创建一个母模板base.html
,不过在创建模板之前还需要在post下面创建个templates
文件夹专门用来放html模板,这个是必须操作,因为在view的方法里面对模板进行引用时,Django只会在这个叫templates
的文件夹下面找模板.然后在templates
文件夹下面创建一个post
文件夹,post这个app的模板就放在这里面了.
<!-- post/base.html -->{% load static %}<head> ???<link rel="stylesheet" type="text/css" href="{% static ‘bootstrap/css/bootstrap.min.css‘ %}" ?????????integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> ???{% block title %}<title></title>{% endblock %}</head>{% block body %} ???{% block navbar %} ???????<nav class="navbar navbar-inverse"> ???????????<div class="container-fluid"> ???????????????<!-- Brand and toggle get grouped for better mobile display --> ???????????????<div class="navbar-header"> ???????????????????<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" ???????????????????????????data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> ???????????????????????<span class="sr-only">Toggle navigation</span> ???????????????????????<span class="icon-bar"></span> ???????????????????????<span class="icon-bar"></span> ???????????????????????<span class="icon-bar"></span> ???????????????????</button> ???????????????????<a class="navbar-brand" href="{% url ‘post:index‘ %}">Chain</a> ???????????????</div> ???????????????<!-- Collect the nav links, forms, and other content for toggling --> ???????????????<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> ???????????????????<ul class="nav navbar-nav"> ???????????????????????<li class="active"><a href="{% url ‘post:index‘ %}">Home<span class="sr-only">(current)</span></a></li> ???????????????????????<li><a href="{% url ‘post:user‘ ‘chain‘%}">Profile</a></li> ???????????????????</ul> ???????????????</div> ???????????</div> ???????</nav> ???{% endblock %} ???{% block content %} ???{% endblock %}{% endblock %}
没错了,base.html
使用了Bootstrap
,在第一篇文章做准备工作时就已经将Bootstrap的资源放到了static
文件夹下面,所以你这里先加载了static
文件夹,紧接着就对bootstrap进行导入.
base.html
只是给网站固定实现了一个导航栏,后面每一个继承了这个模板的html模板都会有这个模板,而不需要再把导航栏的代码重写一遍.
可以看到,base.html
里面定义了两个block
,我们后面写的子模板就是要在content
这个block里面写我们想展示的内容.
再看,在导航栏的代码里面有一些可点击的链接,href
属性都是用的模板的url
方法动态生成的,具体怎么生成就不说了,拿url ‘post:user‘ ‘chain‘
举例说明一下:
url
是模板功能提供的处理url的方法post:user
可以在post的urls.py
里面找到相对应的,post
是在urls.py
里面的app_name
属性,user
肯定就是urls.py
里面注册url地址时设置的name
属性.chain
,这个只是传到view层的一个参数而已.
具体的.在实现view逻辑的时候就明白了.
View
首页
首页主要是展示文章列表以及一个历史标签列表.
先从数据库获取所有的文章整合到一个list里面传到html进行显示.同样的,要获取标签列表也是一样的方法.
# post/views.pyclass IndexView(generic.TemplateView): ???template_name = ‘post/index.html‘ ???def get_context_data(self, **kwargs): ???????context=super().get_context_data(**kwargs) ???????context[‘posts‘]=Post.objects.all()[:3] ???????context[‘tags‘] = PostTag.objects.all() ???????return contextdef tag(request,tag_name): ???tags = PostTag.objects.filter(tag_name=tag_name) ???posts = tags[0].post_set.all() ???return render(request,‘post/tag_index.html‘,{‘posts‘:posts,‘tag_name‘:tag_name})
对于view逻辑的实现,可以定义一个方法,也可以定义一个类,其实定义成类的话,比定义成方法要好很多,但是因为还不是很熟悉View的各种基类,就先大部分用定义方法的方式了.
在templates/post
文件夹下面创建index.html
和tag_index.html
:
<!-- index.html -->{% extends ‘post/base.html‘ %}{% block title %} ???<title>Chain‘s Blog</title>{% endblock %}{% block content %} ???{% if not posts %} ???????<div class="container"> ???????<div class="page-header" align="center"> ???????????<h1>欢迎来到Chain的博客网站!!!</h1> ???????</div> ???????<div align="center"> ???????????<h1>Chain don‘t have blog....Sorry...</h1> ???????</div> ???????</div> ???{% else %} ???<div class="container"> ???????<div class="page-header" align="center"> ???????????<h1>欢迎来到Chain的博客网站!!!</h1> ???????</div> ???????<div class="col-md-6"> ???????????<ul class="list-group"> ???????????????{% for post in posts %} ???????????????????<li class="list-group-item" style="box-shadow: 5px 5px 5px #3c3c3c"> ???????????????????????<div> ???????????????????????????<a href="{% url ‘post:post‘ post.id %}" style="color: black;text-decoration: none"> ???????????????????????????????<h2>{{ post.post_title }}</h2></a> ???????????????????????</div> ???????????????????????<hr> ???????????????????????<div> ???????????????????????????<h4>{{ post.post_description }}</h4> ???????????????????????</div> ???????????????????????<br> ???????????????????????<a class="btn btn-success" href="{% url ‘post:post‘ post.id %}">查看全文 ???????????????????????</a> ???????????????????</li> ???????????????????<br> ???????????????{% endfor %} ???????????</ul> ???????</div> ???????<div class="col-md-6"> ???????????<div class="col-md-4"> ???????????</div> ???????{% if tags %} ???????????<div class="col-md-4" style="box-shadow: 5px 5px 5px #3c3c3c"> ???????????????<h3>History Tags</h3> ???????????????<ul class="list-group"> ???????????????????{% for tag in tags %} ???????????????????????<a href="{% url ‘post:tag‘ tag.tag_name %}" style="text-decoration: none"> ???????????????????????????<li class="list-group-item"># {{ tag.tag_name }}</li> ???????????????????????</a> ???????????????????{% endfor %} ???????????????</ul> ???????????</div> ???????{% endif %} ???????</div> ???????<div class="col-md-4"></div> ???</div> ???{% endif %}{% endblock %}
<!-- tag_index.html -->{% extends ‘post/base.html‘ %}{% block ?title %} ???<title>Tag:{{ tag_name }}</title>{% endblock %}{% block content %} ???<div class="col-md-3"></div> ???<div class="container col-md-6"> ???????<div class="page-header"><h1 align="center"># {{ tag_name }}</h1></div> ???????<ul class="list-group"> ???????????{% for post in posts %} ???????????????<li class="list-group-item" style="box-shadow: 5px 5px 5px #3c3c3c"> ???????????????????<div> ???????????????????????<a href="{% url ‘post:post‘ post.id %}" style="color: black;text-decoration: none"> ???????????????????????????<h2>{{ post.post_title }}</h2></a> ???????????????????</div> ???????????????????<hr> ???????????????????<div> ???????????????????????<h4>{{ post.post_description }}</h4> ???????????????????</div> ???????????????????<br> ???????????????????<a class="btn btn-success" href="{% url ‘post:post‘ post.id %}">查看全文 ???????????????????</a> ???????????????</li> ???????????????<br> ???????????{% endfor %} ???????</ul> ???</div> ???<div class="col-md-3"></div>{% endblock %}
可以看见两个模板都继承了base.html
,因为在base.html
里面已经引入了Bootstrap
,所以这里可以直接使用Bootstrap对页面进行渲染.
其他的页面的实现,和首页差不多,只不过在文章详情页面为了加入Markdown有些小细节要注意,下一篇文章再做详细解释.
完章项目已经push到我的github上面.