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的方式部署在本地,這將會是一個大難點,敬請期待~

相關文章
相關標籤/搜索