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