django 及 rest_framework 筆記鏈接如下:
django 入門筆記:環(huán)境及項目搭建
django 入門筆記:數(shù)據(jù)模型
django 入門筆記:視圖及模版
django 入門筆記:Admin 管理系統(tǒng)及表單
django 入門筆記:通用視圖類重構視圖
django_rest_framework 入門筆記:Serializer
django_rest_framework 入門筆記:視圖函數(shù)重構
django_rest_framework 入門筆記:分頁,多條件篩選及權限認證設置
django 自帶 user 字段擴展及頭像上傳](http://www.reibang.com/p/d45a687c3f41)
前面部分將數(shù)據(jù)庫的操作講述了一遍,注意部分我們終于可以看到些真實的東西了纽门,而不是數(shù)據(jù)...數(shù)據(jù)...數(shù)據(jù)...
創(chuàng)建 django 視圖
普通視圖
- 首先在應用文件夾下創(chuàng)建 urls.py 文件娄柳,用來配置視圖的 url零蓉,然后我們需要在項目下的 urls.py 文件中將該應用的 urls 配置進去
# 在項目下 urls.py 文件配置應用的 urls.py 文件 from django.conf.urls import url, include from django.contrib import admin urlpatterns = [ url(r'^admin/', admin.site.urls), # include 作用:在 django 匹配 url 時候匹配完 blog/ 后糜工,再次匹配下層地址捕传,所以在 blog/ # 后面不可以添加 "$" 符號筐骇,不然會導致不能匹配到地址债鸡,namespace 為了區(qū)分不同應用下同名的模版 url(r'^blog/', include('blog.urls', namespace="blog")), ]
- 在應用文件夾下的 views.py 文件中加入視圖
from django.http import HttpResponse def home(request): return HttpResponse("Hello django")
- 在應用下的 urls.py 文件中將視圖文件配置進去
from django.conf.urls import url from . import views # 加上 app_name, 值同 include 中 namespace 的值,否則可能會找不到 url app_name = 'blog' urlpatterns = [ # 當模版引用本地 url 時候需要用到 name 字段值铛纬,例如 # <a href="{% url 'blog:home' %}"><b>Home</b></a> url(r'^home$', views.home, name=home), ]
- 命令行將代碼運行
然后可以通過網(wǎng)址 "http://192.168.x.xxx:8080/blog/index" 訪問編寫的界面厌均,應該是下面這個樣子的(原諒我偷懶沒有改 ip)python manage.py runserver 192.168.x.xxx:8080
第一個 django 界面
-
當 url 中帶入?yún)?shù)進行傳遞時,例如
def hours_ahead(request, offset): try: offset = int(offset) except ValueError as e: print(e) dt = datetime.datetime.now() + datetime.timedelta(hours=offset) return HttpResponse("{} hours later is {}".format(offset, dt))
那么我們在 url 配置的時候需要將 offset 參數(shù)傳入到 url 中去告唆,需要涉及到正則表達式
urlpatterns = [ # ?P<offset> 為傳遞的參數(shù)字段名棺弊,緊隨其后的是參數(shù)值的匹配正則 # 可以通過 http://192.168.x.xxx:8080/time/ahead/(offset)/ 來訪問相應網(wǎng)址 url(r'^time/ahead/(?P<offset>\d{1, 2})/$', view.hours_ahead, name="time_ahead") ]
帶參數(shù)reverse() 在配置 url 時候的大用處(這里先提下模她,項目中會接觸到)
# 假設我們有個網(wǎng)址為 192.168.x.xxx:8080/post/1/ 其中 1 為 post 的 id 根據(jù) id 不同顯示不同 post # 網(wǎng)址的正則為 url(r'post/(?P<pk>[0-9]+)/$', view.post, name="post_detail") class Post(models.Model): title = models.CharField("標題", max_length=100) def get_post_url(self): # reverse 會自動指向 'blog:post_detail' 所指向的 url,kwargs 為傳入的參數(shù)值 return reverse('blog:post_detail', kwargs={'pk': self.pk})
上面我們提到了正則表達式,這里把 python 常用的正則語法列一下吻氧,方便學習
語法 說明 表達式 匹配 字符串 匹配自身 abc abc . 匹配換行符外任意字符 a.c abc \ 轉(zhuǎn)義字符,使字符改變原來意思 a.c a.c [] 字符集歌溉,對應位可以是字符集任意字符 a[bc]d acd \d 數(shù)字:[0-9] o\do o2o \D 非數(shù)字 a\Dc a,c \s 空白字符[<Space>, \t,\r,\n,\f,\v] a\sc a c \S 非空白字符 a\Sc abc \w 單詞字符:[A-Za-z0-9_] a\wc abc \W 非單詞字符 a\Wc a c * 匹配前一個字符串 0 或者無限次 c[acv]* c + 匹配前一個字符串 1 或者無限次 c[acv]+ ca ? 匹配前一個字符串 0 或者 1 次 cc? c {m} 匹配前一個字符串 m 次 ac{2} acc {m, n} 匹配前一個字符串 m 到 n 次 ac{1, 3} acc ^ 匹配字符串開頭电抚,必須以緊隨的字符開頭 ^abc abc $ 匹配字符串末尾 abc$ abc | 表示左右表達式任意匹配一個 abc|def def
書寫界面的時候公给,我們不可能每次都去 view 界面寫,而且在 view 界面寫也不能給頁面增加特效它匕,接著就需要發(fā)揮模版的作用了
使用模版創(chuàng)建視圖
-
首先在項目根目錄下創(chuàng)建 templates 文件夾础嫡,用來放視圖模版,然后在項目下的 settings.py 文件中注冊 templates 文件夾号阿,使 django 能夠在 templates 文件夾中找到相應的模版湖雹,在 TEMPLATES 中的 DIRS 列表中加入如下代碼
'DIRS': [os.path.join(BASE_DIR, 'templates')],
-
在 templates 文件夾下再創(chuàng)建放應用模版的文件夾 例如 blog 癣籽,然后在 blog 創(chuàng)建 index.html 作為 index 視圖的模版
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>{{ title }}</title> </head> <body> <h1>{{ welcome }}</h1> </body> </html>
-
修改視圖文件函數(shù)
from django.shortcuts import render def index(request): # context 中的參數(shù)名和模版中 {{ }} 包裹的相同 return render(request, 'blog\index.html', context={ 'title': "My Blog Home", 'welcome': "Welcome to My Blog" }) # 或者可以用以下方法來寫 def index(request): title = "My Blog Home" welcome = "Welcome to My Blog" return render(request, 'blog\index.html', locals())
然后我們就可以看到如下的界面,django 會把 view 的值傳到模版中去
第一次使用模版使用模版的話劈彪,我們就需要了解一下模版內(nèi)置的標簽和過濾器翰舌,這對我們?nèi)蘸蟮拈_發(fā)可以提高很多效率
-
django 內(nèi)置模版標簽
{% extends %} 繼承模版標簽
用兩個大括號括起來的文字 (例如 {{ post_title }}) 稱為變量 (variable)驾胆,這意味著在此處插入指定變量的值
-
{% if %} [{% else %} 可省略] {% end if%} 標簽
- {% if %} 標簽接受 and, or 或者 not 關鍵字來對多個變量做判斷,或者對變量取反 (not);
- 不允許在同一個標簽中同時使用 and 和 or,但可以多次使用同一個邏輯操作符;
- 不支持用圓括號來組合比較操作;
- 沒有 {% elif %} 標簽,只能 {% if %} 嵌套達到效果;
- 一定要用 {% endif %} 關閉每一個 {% if %} 標簽
eg:
{% if {{ str }} %} <p>Value is not null</p> {% else %} <p>Value is null</p> {% endif %}
-
{% for %} [{% empty %} 可省略] {% endfor %} 標簽
給標簽增加一個 reversed 使得該列表被反向迭代 eg: {% for s in s_list reversed%}
可以嵌套使用 {% for %} 標簽
執(zhí)行循環(huán)之前通常先檢測列表的大小惩妇,因此 for 標簽支持一個可選的 {% empty %} 分句
不支持 break 和 continue,退出循環(huán)時候歌殃,可以改變正在迭代的變量,讓其僅僅包含需要迭代的項目路召。
-
每個 {% for %} 循環(huán)里有一個稱為 forloop 的模板變量,這個變量存在一些表示循環(huán)進度信息的屬性埠帕,模板解析器碰到{% endfor %}標簽后秤标,forloop就不可訪問了
forloop.counter/counter0
循環(huán)的執(zhí)行次數(shù)的整數(shù)計數(shù)器,從1/0開始計數(shù)
forloop.revcounter/revcounter0
循環(huán)執(zhí)行后的剩余項數(shù)量宙刘,首次執(zhí)行為總數(shù)/總數(shù)減一衙猪,最后置為1/0
forloop.first/last 首次/最后一次迭代為 True
forloop.parentloop 當前循環(huán)的上一級循環(huán)的 forloop 對象的引用(嵌套循環(huán)情況下)
eg:
{% for country in countries %} <table> {% for city in country %} <tr> <td>Country {{ forloop.parentloop.counter }}</td> <td>City {{ forloop.counter }}</td> <td>{{ city }}</td> </tr> {% endfor %} </table> {% empty%} <p>There is no country</p> {% endfor %}
{% ifequal/ifnotequal%} [{% else %}可省略] {% endifqual/ifnotequal%} 標簽
比較兩個變量的值并且顯示一些結(jié)果,支持可選的 {% else%} 標簽布近;只有模板變量垫释,字符串,整數(shù)和小數(shù)可以作為 {% ifequal %} 標簽的參數(shù)
{% autoescape %}{% endautoescape %} 關閉代碼塊中的自動轉(zhuǎn)義撑瞧,父類已經(jīng)關閉則子類也關閉
-
django 常用內(nèi)置模版過濾器
模板過濾器是在變量被顯示前修改它的值的一個簡單方法棵譬,以 "|" 拼接,過濾器的參數(shù)跟隨冒號之后并且總是以雙引號包含预伺,例如 {{ value|add:"2" }} 返回值為 value + 2 的值add:"n"订咸,對象相加曼尊,如果是數(shù)字則是數(shù)字加法,列表則是列表的和脏嚷,無法相加為空骆撇。
addslashes,增加反斜杠然眼,處理 Javascript 文本非常有用
truncatewords:"n"艾船,顯示變量前 n 個字符
pluralize:"y, ies",單詞的復數(shù)形式高每,可以通過參數(shù)設置復數(shù)形式
date:"xxx"屿岂,按指定的格式字符串參數(shù)格式化 date 或者 datetime 對象,例如 {{ pub| date:"F j, Y" }} length鲸匿,返回變量的長度爷怀;對于列表,返回列表元素的個數(shù)带欢。對于字符串运授,返回字符串中字符的個數(shù)
safe,當系統(tǒng)設置 autoescaping 打開的時候乔煞,該過濾器使得輸出不進行 escape 轉(zhuǎn)換
striptags吁朦,刪除 value 中的所有 HTML 標簽
.......
-
django 自定義過濾器和標簽
- 在應用目錄下創(chuàng)建 templatetags 文件夾,同時建立空文件 __ init __.py 和過濾器文件 例如 custom_filter.py
- 在 custom_filter.py 文件中添加過濾器
from django import template from blog.models import Category # register 是 template.Library 的實例渡贾,是所有注冊標簽和過濾器的數(shù)據(jù)結(jié)構 register = template.Libary() # 自定義過濾器 @register.filter def get_value(dic, key_name): return dic.get(key_name) @register.filter def get_attr(d, m): if hasattr(d, m): return getattr(d, m) # 自定義標簽 @register.simple_tag def get_all_category return Category.objects.all()
引用自定義過濾器時需要先導入再使用
{% load custom_filter %} <html lang="en"> <body> <h1>{{ articles|get_value:"article"|get_attr:"id" }}</h1> {% get_all_category as category_list%} <ul> {% for category in category_list%} <li> <a href="#">{{ category.name }}</a> </li> {% empty %} There is no category! {% endfor%} </ul> </body> </html>
靜態(tài)文件處理
靜態(tài)文件主要包括我們需要用到的 css,js 文件等空骚,使用靜態(tài)文件我們只需要以下兩步即可
- 在應用目錄下創(chuàng)建 static 文件夾纺讲,可以將常用的 css 文件,js 文件等放入該文件夾
- 在需要引用靜態(tài)文件的模版中做如下處理
{# 引入靜態(tài)文件囤屹,只有加載標簽模版后才能使用 {% static %} 標簽 #} {% load staticfiles %} {# 在需要引入的地方引入相應文件熬甚,例如在 static 文件夾下有個 blog 文件夾,需要引用其 #} {# 中的 css/bootstrap.min.css 文件可以通過如下方式進行引入 #} <link rel="stylesheet" href="{% static 'blog/css/bootstrap.min.css' %}">
最后附上整個項目的地址:blog_project