您好,登錄后才能下訂單哦!
小生博客:http://xsboke.blog.51cto.com
-------謝謝您的參考,如有疑問,歡迎交流
一、靜態(tài)文件
二、路由映射
三、視圖函數(shù)
四、template(模板)基礎(chǔ)
關(guān)于靜態(tài)文件
1.1 首先需要在配置文件settings.py中指定靜態(tài)目錄
STATICFILES_DIRS = (
os.path.join(BASE_DIR,"statics"),
)
1.2 然后在html中使用django模板語言指定靜態(tài)文件
{% load static from staticfiles %}
<link href="{% static "index.css" %}" rel="stylesheet" type="text/css" />
<script src="{% static "index.js" %} "></script>
1.3 也可以這樣寫
# 指定前綴
STATIC_URL = '/a/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR,"statics"),
)
<link href="/a/css/index.css" rel="stylesheet" type="text/css" />
<script src="/a/js/index.js"></script>
路由映射
Django URL是一個(gè)URL和視圖函數(shù)的映射表
urlpatterns = [
path('admin/', admin.site.urls),
]
urlpatterns = [
url(正則表達(dá)式,views視圖函數(shù),參數(shù),別名)
]
參數(shù):可選的要傳遞給視圖函數(shù)的默認(rèn)參數(shù)
別名:一個(gè)可選的name參數(shù),用于前端
注意:要想使用url去配置路徑需要加載模塊:from django.conf.urls import url
2.1 無名分組
url(r'^articles/[0-9]{4}/([0-9]{4})/([0-9]+)/$',views.special_case_2018),
^articles:以articles開頭匹配articles
/:目錄符號(hào)
[0-9]{4}:包含一個(gè)4位數(shù),每一位的范圍是0-9
():加括號(hào)的意思是傳入一個(gè)參數(shù)
這時(shí)候,views.py需要這樣寫(使用HttpResponsen需要導(dǎo)入這個(gè)模塊):
def special_case_2018(req,變量) #可以傳入多個(gè)變量,用逗號(hào)分隔
return HttpResposen(變量+"year") #將用戶輸入的內(nèi)容返回到瀏覽器上
2.2 命名分組
2.2.1 講解
import re
ret = re.search('(?P<id>\d{3})/(?P<name>\w{3})','weeew34ttt123/ooo')
?P:固定格式,意思是這種分組是有名字的
<id>:匹配的名字就是id,可以看做是一個(gè)變量,是匹配內(nèi)容的變量
\d{3}:是匹配的內(nèi)容,3個(gè)數(shù)字。
\w{3}:就是3個(gè)字母
'weeew34ttt123/ooo':這段字符串就是被匹配的內(nèi)容,最終結(jié)果會(huì)匹配出"123/ooo"
print(ret.group()) :取出所有匹配到的內(nèi)容
print(ret.group('id')) :只取出名字為的id的內(nèi)容
print(ret.group('name')):只取出名字為的name的內(nèi)容
2.2.2 url格式
urlpatterns = [
url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{4})/$',views.year_archive),
]
views.py配置
def year_archive(req,year,month): # 使用命名分組,形參必須是url中定義的名字,順序可以不同
return HttpResposen(year+"y"+month+"m")
2.3 參數(shù)三
urlpatterns = [
url(r'index',views.index,{"name":'dashan'}),
]
def index(req,name):
return HttpResposen(name) # 返回"dashan"
# 如果在使用參數(shù)的同時(shí),使用了命名分組,兩邊的名字如果一樣,那么參數(shù)會(huì)覆蓋命名分組
2.4 參數(shù)四
urlpatterns = [
url(r'index',views.index,name="dashan"), # name是固定的寫法,name就是別名
] # name="dashang",代替的就是index,就是index的別名
這時(shí)候,前端可以通過別名去找到視圖函數(shù)
<form action={% url "dashan" %} method="post">
<input type="text" name="usernmae">
<input type="passwrod" name="passwd">
<input type="submit" name="submit">
<form>
2.5 url映射分發(fā)(include)
當(dāng)有上萬頁面時(shí),你就得在urls.py中寫上萬條url匹配,造成數(shù)據(jù)量大,容易寫重,容易造成結(jié)藕
解決方法:在每個(gè)app下創(chuàng)建一個(gè)urls.py,全局的urls.py只做一個(gè)映射
2.5.1 全局urls.py
from django.conf.urls import url,include
from appname import views
urlpatterns = [
url(r'^appname',include('appname.urls')),
]
2.5.2 app的urls.py
from django.conf.urls import url,include
urlpatterns = [
url(r'page1/page1.1',views.page1), # page1是緊跟appname的內(nèi)容
url(r'page2',views.page2),
]
視圖函數(shù)
HTTP請(qǐng)求中產(chǎn)生兩個(gè)核心對(duì)象:
http請(qǐng)求:HttpRequest對(duì)象
http響應(yīng):HttpResponse對(duì)象
所在位置:django.http
# 獲取兩種請(qǐng)求方法
request.POST.get
request.GET.get
3.1 HttpRequest對(duì)象的屬性
path: 請(qǐng)求頁面的全路徑,不包括域名
method: 請(qǐng)求中使用的HTTP方法的字符串表示,全大寫表示。例如GET和POST
if req.method == "POST" or req.method == "GET"
GET: 包含所有HTTP GET參數(shù)的類字典對(duì)象
POST: 包含所有HTTP POST參數(shù)的類字典對(duì)象
服務(wù)器收到空的POST請(qǐng)求的情況也是可能發(fā)生的,也就是說,表單form通過
HTTP POST方法提交請(qǐng)求,但是表單中可能沒有數(shù)據(jù),因此不能使用
if req.POST 來判斷是否使用的HTTP POST 方法,應(yīng)該使用 if req.method == "POST"
COOKIES: 包含所有cookies的標(biāo)準(zhǔn)python字典對(duì)象;key和values都是字符串
FILE: 包含所有上傳文件的類字典對(duì)象;files中的米一個(gè)key都是<input type="file" name="" />標(biāo)簽中
name的屬性值,files中的每一個(gè)values同時(shí)也是一個(gè)標(biāo)準(zhǔn)的python字典對(duì)象,包含下面是哪個(gè)keys:
filename: 上傳文件名,用字符串表示
content_type: 上傳文件的Content Type
content: 上傳文件的原始內(nèi)容
user: 是一個(gè)Django.contrib.auth.models.User對(duì)象,代表當(dāng)前登錄的用戶,如果訪問用戶當(dāng)前沒有登錄,
user將初始化為django.contrib.auth.models.AnonymousUser的實(shí)例。你可以通過user的
is_authenticated()方法來辨別用戶是否登錄:
if req.user.is_authenticated();只有激活Django中的AuthenticationMiddleware時(shí),該屬性
才可用
session: 唯一可讀寫的屬性,代表當(dāng)前會(huì)話的字典對(duì)象;只有激活Django中的session支持時(shí)該屬性才可用
3.2 HttpResponse對(duì)象
對(duì)于HttpRequest對(duì)象來說,是由django自動(dòng)創(chuàng)建的,但是,HttpResponse對(duì)象就必須我們自己創(chuàng)建,
每個(gè)view請(qǐng)求處理方法必須返回一個(gè)HttpResponse對(duì)象。
HttpResponse類在django.http.HttpResponse
在HttpResponse對(duì)象上擴(kuò)展的常用方法:
頁面渲染: render(),render_to_response(),
# 使用render_to_response()方法需要引入render_to_response模塊
return render(req,"index.html")
return render_to_response("index.html") -- 有坑不建議使用
本地變量:locals(): 可以直接將函數(shù)中所有的變量傳給模板,locals是本地變量的意思,將本地變量傳入html中
例:
views.py 中寫
name="dashan"
return render_to_response("index.html",{"a":name})
html就得寫
{{ a }}
當(dāng)views.py 這樣寫
name="dashan"
return render_to_response("index.html",locals())
html就可以這樣寫,直接調(diào)用變量,而不需要使用參數(shù)調(diào)用
{{ name }}
注意,使用render也可以
頁面跳轉(zhuǎn)(重定向): redirect()
return redirect("http://www.baidu.com")
return redirect("http://www.baidu.com")
render 是直接渲染某個(gè)頁面并返回,redirect是重定向到指定的views函數(shù),同時(shí)也會(huì)做一定的判斷,
比如用戶登錄。
template基礎(chǔ)
在向前端輸出字符串時(shí)使用模板語言進(jìn)行處理,而不是使用 "歡迎 %s 登錄" %(name) ,這種方式是為了實(shí)現(xiàn)前后端分離
什么是模板語言?
格式:HTML + 邏輯控制語句,如果HTML中存在模板語言,則HTML就叫模板,而不是HTML
模板語言的作用?
起到前端到后端的紐帶作用
render(request,"index.html",{"name":name})
"index.html" 就叫模板
{"name":name} 就叫上下文,Context
在pycharm的terminal界面輸入python manage.py shell即可進(jìn)入當(dāng)前django的命令行
輸入:
>>> t=Template("hello {{ name }}") 創(chuàng)建模板語言
>>> c=Context({"name":"dashan"}) 創(chuàng)建上下文
>>> t.render(c) 渲染模板語言和上下文
'hello dashan'
4.1 一次模板創(chuàng)建,多次調(diào)用render()實(shí)現(xiàn)更高效的渲染
t = Template("hello, {{ name }}")
for name in ('dashan','lisi','wangwu'):
print t.render(Context({'name'}:name))
在view中使用Template和Context需要引入,from django.template import Template,Context
4.2 深度變量的查找(萬能的句點(diǎn)號(hào)".")
import datetime
def index(req):
s=[1,2,3,4]
s2={"uname":"dashan","sex":23}
s3=datetime.datetime.now()
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
s4=Person("dashan",18)
return render(req,"index.html",{"list":s})
return render(req,"index.html",{"obj":s2})
return render(req,"index.html",{"time":s3})
return render(req,"index.html",{"P":s4})
<html>
<p> Template </p>
{{ list.2}} <!-- 輸出的結(jié)果是3 ,列表通過索引取值-->
{{ obj.sex}} <!-- 輸出的結(jié)果是23,字典通過key取values -->
{{ time.year }} <!-- 屬性也是通過"."召喚出來的 -->
{{ time.month }} <!-- 屬性也是通過"."召喚出來的 -->
{{ P.age }} <!-- 屬性也是通過"."召喚出來的,結(jié)果是18 -->
{{ P }} <!-- 如果不加屬性,那么輸出的是一個(gè)對(duì)象屬性 -->
</html>
4.3 if和for循環(huán)
4.3.1 if,只支持布爾值True或者False,1(True)和(False)也可以
{ % if True % }
<p>hello world</p>
{ % elif obj % }
<p>hello2</p>
{ % endif % }
4.3.2 for
# 用列表舉例
{ % for i in list % }
<p>{{ i }}</p> <!-- i 是vaules,和js不一樣(js取的是索引) -->
<p>{{ forloop.counter }}:{{ i }}</p> <!-- 輸出"索引值:values",索引從1開始 -->
<p>{{ forloop.counter0 }}:{{ i }}</p> <!-- 輸出"索引值:values",索引從0開始 -->
<p>{{ forloop.revcounter }}:{{ i }}</p> <!-- 輸出"索引值:values",索引反著打印 -->
{ % endfor % }
# 用字典舉例
{ % for i in obj % }
<p>{{ forloop.counter }}:{{ i }}</p> <!-- 輸出"索引值:key",索引從1開始,和列表一樣 -->
<p>{{ forloop.counter }}:{{ i.uname }}</p> <!-- 輸出"索引值:values",這樣就可以打印值了 -->
{ % endfor % }
# 字典的使用方法
{% for row in user_dict.keys %}
{% for row in user_dict.values %}
{% for row in user_dict.items %} 得到元組
{% for k,row in user_dict.items %}
<li>{{k}}-{{row}}</li>
{% endfor %}
4.4 過濾器filter
{{ ship_date|date:"Fj,Y"}}
ship_date變量傳給date過濾器,date過濾器通過使用"Fj,Y"這幾個(gè)參數(shù)來格式化日期數(shù)據(jù),
"|"和unix的管道符類似
s = "hello"
s2 = 1
s3 = datetime.datetime.now()
s4 = []
s5 = "<a
return render(req,"index.html",{"obj":s})
return render(req,"index.html",{"num":s2})
return render(req,"index.html",{"time":s3})
return render(req,"index.html",{"kong":s4})
return render(req,"index.html",{"a":s5})
<html>
{{ 對(duì)象|方法:參數(shù)}} - 格式
{{ obj }} - 打印結(jié)果"hello".
{{ obj|upper }} - 使用模板語言中的upper方法,將"hello"轉(zhuǎn)為大寫"HELLO".
{{ obj|lower }} - 小寫
{{ obj|firest }} - 取出第一個(gè)字母
{{ obj|capfirest }} - 將第一個(gè)字母大寫
{{ num|add:5 }} - num+5 ,結(jié)果為6
{{ 對(duì)象|cut: ' '}} - 去除空格
{{ time|date: 'Y-m-d'}} - 輸出年月日,"-"也可以寫為":"
{{ kong|default: '空的'}} - 當(dāng)對(duì)象為空時(shí),輸出default指定的字符串,如果不為空則輸出對(duì)象
{{ % a % }} - 會(huì)將超鏈接返回為一個(gè)字符串,因?yàn)闉g覽器會(huì)認(rèn)為是不安全的
{ % autoescape off % } - 這樣瀏覽器就能解析為html語言了,瀏覽器就認(rèn)為是安全的
{{ % a % }}
{ % endautoescape % }
{{ a|safe }} - 這個(gè)和上面那個(gè)是一樣的功能,會(huì)告訴瀏覽器這是安全的
{{ obj|filesizeformat }} - 打印對(duì)象的大小
{{ obj|length }} - 打印對(duì)象的長度
{{ obj|slice: ':-1' }} - 切片,從頭切到最后一個(gè),最后一個(gè)不要
{{ a|urlencode }}
values="hello I am shan"
{{ values|truncatechars:'6' }} 按字符截取
{{ values|truncatewords:'2' }} 按單詞截取
</html>
注意:為什么要在前端轉(zhuǎn)而不是后端,試想一下如果輸入的是一個(gè)字典類型的數(shù)據(jù),需要
for循環(huán)完后的數(shù)據(jù)輸出為大寫,如果你在后端做這個(gè)操作的話就會(huì)變得很繁瑣,需要
循環(huán)完后賦予一個(gè)變量才能轉(zhuǎn)給前端
4.5 中間件 csrf 跨站請(qǐng)求偽造
用于生成csrf_token的標(biāo)簽,用于防治跨站***驗(yàn)證。
用于驗(yàn)證form表單
<form action="/login" method="post" >
<p>姓名:<input type="text" name="username"></p>
<p>性別:<input type="text" name="sex"></p>
<p>郵箱:<input type="text" name="email"></p>
<p><input type="submit" value="submit"></p>
{% csrf_token %} <!-- 指定認(rèn)證,否則報(bào)錯(cuò)Forbidden
django會(huì)渲染出一個(gè)令牌(input標(biāo)簽),
擁有類型hidden,名字和值,用于告訴Django,
我是一個(gè)認(rèn)證過的表單
-->
</form>
注意:
同時(shí)如果你在views.py中返回頁面時(shí)使用 render_to_response,需要這樣寫
from django.template import RequestContext,Template
return render_to_response("index.html",context_instent=RequestContext(request))
否則也會(huì)報(bào)錯(cuò)Forbidden,所以之前才不建議使用render_to_response
4.6 { % load % } - 加載標(biāo)簽庫
4.7 { % url % } - 引用路由配置的地址
4.8 { % with % } - 用更簡單的變量名替代復(fù)雜的變量名
{ % with total=fadsfsadfdsaffdsaf % } {{ total }} { % endwith % }
格式:{ % with 新變量名=舊變量名 % } {{ 新變量名 }} { % endwith % }
4.9 { % varbatim % } - 禁止render
{ % varbatim % } - name就不會(huì)渲染了,輸出的就是字符串"{{ name }} "
{{ name }}
{ % endvarbatim % }
4.10 自定義 simple_tag
需求:比如后端傳給了前端一個(gè)變量num=1,我想讓這個(gè)變量在前端+10,
原本我可以在前端寫為 {{ num|add:'10'}},但是我想使用自定義的方法
{{ num|add100 }},這就叫做自定義simple_tag(簡單標(biāo)簽)
a. 在app目錄下中創(chuàng)建templatetags模塊
b. 創(chuàng)建任意.py文件,如文件名"my_tag.py"
#!/usr/bin/evn python
#coding:utf-8
from django import template
from django.utils.safestring import mark_safe
register = template.Library() # register是固定變量名,不能改變
@register.simple_tag # 裝飾器
def my_add100(v1):
return v1 + 10 # 實(shí)現(xiàn)num+10
@register.simple_tag
def my_input(id,arg):
result = "<input type="text" id="%s" class="%s">" %(id.arg)
return mark_safe(result)
c. 在使用自定義simple_tag的html文件中引入之前創(chuàng)建的mytag.py文件名
{ % load my_tag % }
<html>
</html>
d. 使用simple_tag
<html>
{ % my_add100 1 % } <!-- 輸出11 -->
</html>
<html>
{ % my_input id1 cl1 % } <!-- 輸出一個(gè)input標(biāo)簽,id是id1,class是cl1 -->
</html>
4.11 自定義filter
流程和自定義 simple_tag一樣,就差在
@register.simple_tag了,自定義filter是這樣寫@register.filter
調(diào)用方式為
{{ num|my_add100 }} <!-- 輸出11 相當(dāng)于執(zhí)行"my_add100(num)" -->
如果自定義filter傳入的是兩個(gè)參數(shù),最多也只能兩個(gè)(自定義 simple_tag沒有這個(gè)限制),
解決方法是傳入一個(gè)列表
@register.filter # 裝飾器
def my_add100(v1,v2):
return v1 + 10 + v2
{{ num|my_add100:2 }} <!-- 輸出13 -->
注意:模板的if語句可以加一個(gè)自定義filter,但是不能加自定義simple_tag
同時(shí),使用自定義簡單標(biāo)簽和自定義filter,必須在全局文件settings.py中的
INSTALLED_APPS [
'myapp',
]
區(qū)域添加你的app名
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。