Django的基本使用
小生 Q Q:1770058260
-------謝謝您的參考,如有疑問,歡迎交流
一、靜態文件
二、路由映射
三、視圖函數
四、template(模板)基礎
-
關於靜態文件
1.1 首先需要在配置文件settings.py中指定靜態目錄
STATICFILES_DIRS = (
os.path.join(BASE_DIR,"statics"),
)1.2 然後在html中使用django模板語言指定靜態文件
{% load static from staticfiles %}
<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 reret = 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 href="http://www.baidu.com">百度</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名
Django的基本使用