Django+Nginx+uwsgi搭建本身的博客(四)

因为在上篇博文中仍然介绍了至关多的后端部分,致使原定于上篇介绍的前端部分“跳票”到了这篇。在此篇博文中,我将会介绍Users App和主页的前端部分,从而造成咱们博客的一个雏形。css

在前端部分,咱们主要使用前端模板来创建咱们的网页。Django提供了默认的模板引擎供咱们使用。借助模板引擎,咱们能够方便地将服务器的数据显示在页面中,实现先后端的交互。此外,模板的另外一个好处是可继承性。借助模板继承,咱们能够创建一个父模板,而后在其中填入不一样的内容来快速创建不一样的页面,从而大大减小了咱们的工做量。html

前端部分分为App和主页两部分。App的前端主要对应App中的views.py中的各个视图函数,而主页的前端是用于对应myblog/views.py中的视图函数的。前端

咱们首先来创建主页的前端部分。在myblog目录下,创建一个名为templates的文件夹,这里是咱们存放模板的目录,咱们会把父模板和子模板的目录都放在这里。进入该目录,并在其中再创建一个名为myblog的目录,在这里是咱们存放子模板的地方,目录结构以下:python

 

  1. ├── templates  
  2. │   ├── myblog  
  3. │   │   ├── 404.html  
  4. │   │   └── index.html  
  5. │   └── parentTemplate.html  
├── templates
│   ├── myblog
│   │   ├── 404.html
│   │   └── index.html
│   └── parentTemplate.html

咱们要在templates目录中创建名为parentTemplate.html的文件做为咱们的父模板,代码以下:

 

  1. <!DOCTYPE html>  
  2. <html lang="zh">  
  3. <head>  
  4.     <meta charset="UTF-8">  
  5.     <title>Cap_Liu的博客</title>  
  6. </head>  
  7. <style type="text/css">  
  8.     body{  
  9.         color: #efd;  
  10.         background: #F3F8C5;  
  11.         margin:7px;  
  12.     }  
  13.     h1{  
  14.         padding: 2em;  
  15.         background: #675;  
  16.     }  
  17.     h2{  
  18.         color: #000000;  
  19.         margin-top:2em;  
  20.         text-align: center;  
  21.     }  
  22.     p{  
  23.         margin:1em 0;  
  24.     }  
  25.     .introduce{  
  26.         color: #000000;  
  27.         margin-left: auto;  
  28.         margin-right: 85%;  
  29.     }  
  30.     .list{  
  31.         color: #000000;  
  32.         margin-left: auto;  
  33.         position:relative;  
  34.         left: 20%;  
  35.         top: -20px;  
  36.     }  
  37.     .nav{  
  38.         color: #000000;  
  39.         top: -20px;  
  40.         text-align: right;  
  41.     }  
  42.     .content{  
  43.         color: #000000;  
  44.         top: -20px;  
  45.     }  
  46.     .content p{  
  47.         text-indent: 5em;  
  48.     }  
  49.     .articlelist{  
  50.         text-align: left;  
  51.                 font-size: 20px;  
  52.     }  
  53.     .articlelistinfo{  
  54.         text-align: left;  
  55.         font-size: 20px;  
  56.     }  
  57.       
  58. </style>  
  59. <body>  
  60. <h1>BetrayArmy的博客</h1>  
  61. <div class="introduce">  
  62. {% block introduce %}  
  63. {% endblock %}  
  64. </div>  
  65. <div class="nav">  
  66. {% block nav %}  
  67. {% endblock %}  
  68. </div>  
  69. <div class="content">  
  70. {% block content %}  
  71. {% endblock %}  
  72. </div>  
  73. </body>  
  74. </html>  
<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>Cap_Liu的博客</title>
</head>
<style type="text/css">
    body{
        color: #efd;
        background: #F3F8C5;
        margin:7px;
    }
    h1{
        padding: 2em;
        background: #675;
    }
    h2{
        color: #000000;
        margin-top:2em;
		text-align: center;
    }
    p{
        margin:1em 0;
    }
	.introduce{
		color: #000000;
		margin-left: auto;
		margin-right: 85%;
	}
	.list{
		color: #000000;
		margin-left: auto;
		position:relative;
		left: 20%;
		top: -20px;
	}
	.nav{
		color: #000000;
		top: -20px;
		text-align: right;
	}
	.content{
	    color: #000000;
		top: -20px;
	}
	.content p{
		text-indent: 5em;
	}
	.articlelist{
		text-align: left;
                font-size: 20px;
	}
	.articlelistinfo{
		text-align: left;
		font-size: 20px;
	}
	
</style>
<body>
<h1>BetrayArmy的博客</h1>
<div class="introduce">
{% block introduce %}
{% endblock %}
</div>
<div class="nav">
{% block nav %}
{% endblock %}
</div>
<div class="content">
{% block content %}
{% endblock %}
</div>
</body>
</html>
在模板中,使用{% block name %}和{% endblock %}来定义模板的内容块,咱们能够在子模板中填写对应块的内容。这个父模板很简单,定义了一些CSS样式以及定义了三个div:我的介绍introduce,导航栏nav,以及内容区content。

而后咱们开始编写咱们的子模板templates/myblog/index.html。该html是真正的主页,它会继承以上的父模板,并负责将myblog/views.py中的index函数返回的数据显示在上面三个内容块中,代码以下:nginx

 

  1. <!--templates/myblog/index.html-->  
  2. {% extends "parentTemplate.html" %}  
  3.   
  4. {% block introduce %}  
  5. {% if curruser.username  != "anony" or curruser.username  != "" %}  
  6. <div>  
  7. {% if curruser.logoimage %}  
  8. <img src="{{ curruser.logoimage.url }}" width="64" height="64" />  
  9. {% endif %}  
  10. </div>  
  11. <a href="{% url 'users:userInfo' curruser.username %}">{{ curruser.username }}</a>  
  12. {% endif %}  
  13. {% endblock %}  
  14. {% block nav %}  
  15. {% if curruser.username  == "anony" or curruser.username  == "" %}  
  16. <a href="{% url 'users:userregister' %}">用户注册</a>  
  17. <a href="{% url 'users:userlogin' %}">用户登陆</a>  
  18. {% else %}  
  19. 用户:{{ curruser.username }}  
  20. <a href="{% url 'users:logoff' %}">退出登陆</a>  
  21. <a href="{% url 'blogs:addblog' %}">写博文</a>  
  22. {% endif %}  
  23. {% endblock %}  
  24. {% block content %}  
  25. <div class="list">  
  26. {% if blog_list %}  
  27.     <ul>  
  28.     {% for blog in blog_list %}  
  29.         <div class="articlelist">  
  30.         <a href="{% url 'blogs:content' blog.id %}">{{ blog.title }}</a>-<a href="{% url 'users:userInfo' blog.auther.username %}">{{ blog.auther }}</a>  
  31.         <div class="articlelistinfo">  
  32.         <span title="阅读次数">阅读 {{ blog.readcount }}</span>  
  33.         <span title="建立时间">{{ blog.createdate|date:"Y-m-d H:i:s" }}</span>  
  34.         </div>  
  35.         </div>  
  36.     {% endfor %}  
  37.     </ul>  
  38. {% else %}  
  39.     <p>No blogs</p>  
  40. {% endif %}  
  41. </div>  
  42. {% endblock %}  
<!--templates/myblog/index.html-->
{% extends "parentTemplate.html" %}

{% block introduce %}
{% if curruser.username  != "anony" or curruser.username  != "" %}
<div>
{% if curruser.logoimage %}
<img src="{{ curruser.logoimage.url }}" width="64" height="64" />
{% endif %}
</div>
<a href="{% url 'users:userInfo' curruser.username %}">{{ curruser.username }}</a>
{% endif %}
{% endblock %}
{% block nav %}
{% if curruser.username  == "anony" or curruser.username  == "" %}
<a href="{% url 'users:userregister' %}">用户注册</a>
<a href="{% url 'users:userlogin' %}">用户登陆</a>
{% else %}
用户:{{ curruser.username }}
<a href="{% url 'users:logoff' %}">退出登陆</a>
<a href="{% url 'blogs:addblog' %}">写博文</a>
{% endif %}
{% endblock %}
{% block content %}
<div class="list">
{% if blog_list %}
	<ul>
	{% for blog in blog_list %}
		<div class="articlelist">
		<a href="{% url 'blogs:content' blog.id %}">{{ blog.title }}</a>-<a href="{% url 'users:userInfo' blog.auther.username %}">{{ blog.auther }}</a>
		<div class="articlelistinfo">
		<span title="阅读次数">阅读 {{ blog.readcount }}</span>
		<span title="建立时间">{{ blog.createdate|date:"Y-m-d H:i:s" }}</span>
		</div>
		</div>
	{% endfor %}
	</ul>
{% else %}
	<p>No blogs</p>
{% endif %}
</div>
{% endblock %}
这里介绍一下模板语言中的一些关键字:

{% extends "parentTemplate.html" %}:在模板中,使用{% extends 模板名 %}这种关键字来声明该页面继承于哪一个模板。若某网页继承了某模板,其就能够修改父模板的block内容,以及使用定义在父模板中的CSS样式。django

{% block introduct %}:因为继承了parentTemplate模板,所以这里的block名称要与父模板中的block名称同样,以实现填写对应block内容的目的。后端

{% if curruser.username  != "anony" or  curruser.username  != "" %}和{% endif %}:模板语言中的条件判断,每一个{% if %}必需要有一个{% endif %}与之对应。服务器

在模板中,能够直接使用经过服务器传入的python对象,并访问其方法和属性。curruser即为经过myblog/views.py中的index函数传回的对象,以下所示:session

 

[python] view plain copy
print ?
  1. # myblog/views.py  
  2. def index(request):  
  3.     try:  
  4.         username = request.session['username']  
  5.         user = Users.objects.get(username=username)  
  6.     except KeyError:  
  7.         user = Users.objects.get(username='anony')  
  8.     except Users.DoesNotExist:  
  9.         user = Users.objects.get(username='anony')  
  10.     blogList = Blog.objects.filter(draft=False).order_by('title')  
  11.     content = { 'blog_list':blogList,  
  12.                 '<span style="color:#ff0000;">curruser</span>':<span style="color:#ff0000;">user</span>  
  13.                }  
  14.     return render(request, 'myblog/index.html', content)  
# myblog/views.py
def index(request):
    try:
        username = request.session['username']
        user = Users.objects.get(username=username)
    except KeyError:
        user = Users.objects.get(username='anony')
    except Users.DoesNotExist:
        user = Users.objects.get(username='anony')
    blogList = Blog.objects.filter(draft=False).order_by('title')
    content = { 'blog_list':blogList,
                'curruser':user
               }
    return render(request, 'myblog/index.html', content)
在index函数中,经过字典向index.html传递了两个参数:名为curruser的Users类对象和名为blog_list的list对象,而咱们能够在html模板中直接访问这两个对象,包括得到其属性、对其进行遍历等操做。若想访问对象的属性,能够经过.运算符来进行。

{% url ‘users:userregister’ [参数名] %}:html中<a>标签或表单action属性中的url地址。该标签与urls.py中的url列表项一一对应,如users:userregister指的是在Users App中的urls.py文件中的名为userregister项,以下所示:app

 

[python] view plain copy
print ?
  1. # Users App urls.py  
  2. from django.conf.urls import url,include  
  3. from . import views  
  4. from myblog.views import index  
  5.   
  6. app_name='<span style="color:#ff0000;">users</span>'  
  7. urlpatterns = [  
  8.     url(r'^$', index, name='index'),  
  9.     url(r'^userregister/$',views.userregister,name='<span style="color:#ff0000;">userregister</span>'),  
  10.     url(r'^userlogin/$',views.userlogin,name='userlogin'),  
  11.     url(r'^loginResult/(?P<info>.*)$',views.loginResult,name='loginResult'),  
  12.     url(r'^registerResult/(?P<info>.*)$',views.registerResult,name='registerResult'),  
  13.     url(r'^logoff/$',views.logoff,name='logoff'),  
  14.     url(r'^userinfo/(?P<username>.*)$',views.userInfo,name='userInfo')  
  15. ]  
  16. # 红字即为users:userregister的来源  
# Users App urls.py
from django.conf.urls import url,include
from . import views
from myblog.views import index

app_name='users'
urlpatterns = [
    url(r'^$', index, name='index'),
    url(r'^userregister/$',views.userregister,name='userregister'),
    url(r'^userlogin/$',views.userlogin,name='userlogin'),
    url(r'^loginResult/(?P<info>.*)$',views.loginResult,name='loginResult'),
    url(r'^registerResult/(?P<info>.*)$',views.registerResult,name='registerResult'),
    url(r'^logoff/$',views.logoff,name='logoff'),
    url(r'^userinfo/(?P<username>.*)$',views.userInfo,name='userInfo')
]
# 红字即为users:userregister的来源
若url后面有参数,则直接加在url名称后便可。

{% for blog in blog_list %}和{% endfor %}:for循环操做。该循环会遍历blog_list中的每一个元素,并将其相关信息显示在网页中。因为Blog的部分尚未写,所以以前的index函数中的blogList和页面中的这个for循环能够先跳过。

另外一个404.html的模板就相对简单多了,以下所示:

 

  1. <!-- 404.html -->  
  2. {% extends "parentTemplate.html" %}  
  3. {% block content %}  
  4. <div class="list">  
  5. <p>页面未找到!</p>  
  6. <p><a href="{% url 'index' %}">返回首页</a></p>  
  7. </div>  
  8. {% endblock %}  
<!-- 404.html -->
{% extends "parentTemplate.html" %}
{% block content %}
<div class="list">
<p>页面未找到!</p>
<p><a href="{% url 'index' %}">返回首页</a></p>
</div>
{% endblock %}

如今,主页的前端页面已经创建完成,咱们能够如法炮制,创建Users App的前端页面。

咱们回到users文件夹下,一样创建templates目录,而后能够将以前创建好的parentTemplate.html拷贝过来,重命名为userTemplate.html;而后创建users目录,此时users/templates目录结构以下:

 

  1. ├── users  
  2. │   ├── loginResult.html  
  3. │   ├── registerResult.html  
  4. │   ├── userinfo.html  
  5. │   ├── userlogin.html  
  6. │   └── userregister.html  
  7. └── userTemplate.html  
├── users
│   ├── loginResult.html
│   ├── registerResult.html
│   ├── userinfo.html
│   ├── userlogin.html
│   └── userregister.html
└── userTemplate.html

能够看到,Users App的前端部分共有5个页面,分别对应users/views.py中除了logoff函数外的5个view函数。

首先来看userregister.html,这一页面主要就是显示了用户注册的表单,如图所示:



所以其模板也比较简单:从服务器得到表单对象并将其显示出来:

 

  1. <!-- userregister.html -->  
  2. {% extends "userTemplate.html" %}  
  3. {% block content %}  
  4. <h3>新用户注册</h3>  
  5. <form action="{% url 'users:userregister' %}" method="post" enctype="multipart/form-data">  
  6. {% csrf_token %}  
  7. {{ form.as_p }}  
  8. <p><input type="submit" value="提交"></p>  
  9. </form>  
  10. {% endblock %}  
<!-- userregister.html -->
{% extends "userTemplate.html" %}
{% block content %}
<h3>新用户注册</h3>
<form action="{% url 'users:userregister' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<p><input type="submit" value="提交"></p>
</form>
{% endblock %}

这里出现了一个新参数:{% csrf_token %},这是Django提供的csrf校验功能,通常来讲都要加上,防止跨站伪造请求。此外,因为该表单有文件上传功能,所以enctype要设置为"multipart/form-data"。而form为前一篇博文中介绍的ModelForm,经过as_p方法,在页面中会将表单的每项用<p>标签显示出来。

而后就是registerResult.html,这一页面用于显示注册成功与否:

 

  1. <!-- registerResult.html -->  
  2. {% extends "userTemplate.html" %}  
  3. {% block content %}  
  4. <h3>{{ result_info }}</h3>  
  5. <a href="{% url 'index' %}" >返回首页</a>  
  6. {% endblock %}  
<!-- registerResult.html -->
{% extends "userTemplate.html" %}
{% block content %}
<h3>{{ result_info }}</h3>
<a href="{% url 'index' %}" >返回首页</a>
{% endblock %}

接下来是userlogin.html与loginResult.html,这两个页面与userregister.html/registerResult.html基本彻底相同,所以一块放出来:

 

  1. <!-- userlogin.html -->  
  2. {% extends "userTemplate.html" %}  
  3. {% block content %}  
  4. <h3>用户登陆</h3>  
  5. <form action="{% url 'users:userlogin' %}" method="post">  
  6. {% csrf_token %}  
  7. {{ form.as_p }}  
  8. <p><input type="submit" value="登陆"></p>  
  9. </form>  
  10. {% endblock %}  
  11.   
  12. <!-- loginResult.html -->  
  13. {% extends "userTemplate.html" %}  
  14. {% block content %}  
  15. <h3>{{ result_info }}</h3>  
  16. <a href="{% url 'index' %}" >返回首页</a>  
  17. {% endblock %}  
<!-- userlogin.html -->
{% extends "userTemplate.html" %}
{% block content %}
<h3>用户登陆</h3>
<form action="{% url 'users:userlogin' %}" method="post">
{% csrf_token %}
{{ form.as_p }}
<p><input type="submit" value="登陆"></p>
</form>
{% endblock %}

<!-- loginResult.html -->
{% extends "userTemplate.html" %}
{% block content %}
<h3>{{ result_info }}</h3>
<a href="{% url 'index' %}" >返回首页</a>
{% endblock %}
最后一个页面是userinfo.html,用于显示用户信息:

 

  1. <!-- userinfo.html -->  
  2. {% extends "userTemplate.html" %}  
  3. {% block content %}  
  4. <h3>用户{{ username }}资料</h3>  
  5. <p>用户名: {{ username }}</p>  
  6. <p>注册时间: {{ registertime|date:"Y-m-d" }}</p>  
  7. <p>生日: {{ birthday|date:"Y-m-d H:i:s" }}</p>  
  8. <p>电子邮件: {{ email }}</p>  
  9. <p><a href="{% url 'index' %}">返回首页</a></p>  
  10. {% endblock %}  
<!-- userinfo.html -->
{% extends "userTemplate.html" %}
{% block content %}
<h3>用户{{ username }}资料</h3>
<p>用户名: {{ username }}</p>
<p>注册时间: {{ registertime|date:"Y-m-d" }}</p>
<p>生日: {{ birthday|date:"Y-m-d H:i:s" }}</p>
<p>电子邮件: {{ email }}</p>
<p><a href="{% url 'index' %}">返回首页</a></p>
{% endblock %}

注意,这里的registertime和birthday因为在Model中均为DateTimeField,所以咱们须要用|date的方式告诉前端应将其显示成正确的日期或时间格式,不然会显示不正确。

如今,咱们的博客算是有了个基本的雏形,能够在上面注册用户并登陆了。然而,若是如今咱们注册了一个有头像的用户并登陆,咱们会发如今主页上并不能显示出用户头像,这是由于咱们如今并无处理静态文件。在下一篇博客中,我将介绍怎样把咱们的博客使用uwsgi+nginx的方式部署在本地,这将会是一个大难点,敬请期待~

相关文章
相关标签/搜索