URL配置(URLconf)就像Django所支撐網站的目錄。它的本質是URL與要爲該URL調用的視圖函數之間的映射表。css
基本格式:html
from django.conf.urls import url urlpatterns = [ url(正則表達式, views視圖,參數,別名), ]
注意:前端
Django 2.0版本中的路由系統是下面的寫法(官方文檔):python
from django.urls import path,re_path urlpatterns = [ path('articles/2003/', views.special_case_2003), path('articles/<int:year>/', views.year_archive), path('articles/<int:year>/<int:month>/', views.month_archive), path('articles/<int:year>/<int:month>/<slug:slug>/', views.article_detail), ]
基本配置git
from django.conf.urls import url from . import views urlpatterns = [ url(r'^articles/2003/$', views.special_case_2003), url(r'^articles/([0-9]{4})/$', views.year_archive), url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive), url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail), ]
注意事項ajax
補充說明正則表達式
# 是否開啓URL訪問地址後面不爲/跳轉至帶有/的路徑的配置項 APPEND_SLASH=True 默認就是True 若是在settings.py中設置了 APPEND_SLASH=False,此時咱們再請求 http://www.example.com/blog 時就會提示找不到頁面。
上面的示例使用簡單的正則表達式分組匹配(經過圓括號)來捕獲URL中的值並以位置參數形式傳遞給視圖。數據庫
在更高級的用法中,可使用分組命名匹配的正則表達式組來捕獲URL中的值並以關鍵字參數形式傳遞給視圖。django
在Python的正則表達式中,分組命名正則表達式組的語法是(?P
from django.conf.urls import url from . import views urlpatterns = [ url(r'^articles/2003/$', views.special_case_2003), url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive), url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive), url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.article_detail), ]
這個實現與前面的示例徹底相同,只有一個細微的差異:捕獲的值做爲關鍵字參數而不是位置參數傳遞給視圖函數。
URLconf匹配的位置
URLconf 在請求的URL 上查找,將它當作一個普通的Python 字符串。不包括GET和POST參數以及域名。 例如,http://www.example.com/myapp/ 請求中,URLconf 將查找 /myapp/ 。 在http://www.example.com/myapp/?page=3 請求中,URLconf 仍將查找 /myapp/ 。 URLconf 不檢查請求的方法。換句話講,全部的請求方法 —— 同一個URL的POST、GET、HEAD等等 —— 都將路由到相同的函數。
捕獲的參數永遠都是字符串
每一個在URLconf中捕獲的參數都做爲一個普通的Python字符串傳遞給視圖,不管正則表達式使用的是什麼匹配方式。例如,下面這行URLconf 中:
url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
傳遞到視圖函數views.year_archive() 中的year參數永遠是一個字符串類型。
視圖函數中指定默認值
# urls.py中 from django.conf.urls import url from . import views urlpatterns = [ url(r'^blog/$', views.page), url(r'^blog/page(?P<num>[0-9]+)/$', views.page), ] # views.py中,能夠爲num指定默認值 def page(request, num="1"): pass
在上面的例子中,兩個URL模式指向相同的view - views.page - 可是第一個模式並無從URL中捕獲任何東西。
若是第一個模式匹配上了,page()函數將使用其默認參數num=「1」,若是第二個模式匹配,page()將使用正則表達式捕獲到的num值。
include其餘的URLconfs
from django.conf.urls import include, url urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^blog/', include('blog.urls')), # 能夠包含其餘app的URLconfs文件 ]
URLconfs 具備一個鉤子,讓你傳遞一個Python 字典做爲額外的參數傳遞給視圖函數。
django.conf.urls.url() 能夠接收一個可選的第三個參數,它是一個字典,表示想要傳遞給視圖函數的額外關鍵字參數。
from django.conf.urls import url from . import views urlpatterns = [ url(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive, {'foo': 'bar'}), ]
在這個例子中,對於/blog/2005/請求,Django 將調用views.year_archive(request, year='2005', foo='bar')。
當傳遞額外參數的字典中的參數和URL中捕獲值的命名關鍵字參數同名時,函數調用時將使用的是字典中的參數,而不是URL中捕獲的參數。
我們簡單來講就是能夠給咱們的URL匹配規則起個名字,一個URL匹配模式起一個名字。
這樣咱們之後就不須要寫死URL代碼了,只須要經過名字來調用當前的URL。
舉個簡單的例子:
url(r'^home', views.home, name='home'), # 給個人url匹配模式起名爲 home url(r'^index/(\d*)', views.index, name='index'), # 給個人url匹配模式起名爲index
在模板裏面能夠這樣引用:
{% url 'home' %}
在views函數中能夠這樣引用:
from django.urls import reverse reverse("index", args=("2018", ))
例子:
from django.conf.urls import url from . import views urlpatterns = [ # ... url(r'^articles/([0-9]{4})/$', views.year_archive, name='news-year-archive'), # ... ]
根據這裏的設計,某一年nnnn對應的歸檔的URL是/articles/nnnn/。
你能夠在模板的代碼中使用下面的方法得到它們:
<a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a> <ul> {% for yearvar in year_list %} <li><a href="{% url 'news-year-archive' yearvar %}">{{ yearvar }} Archive</a></li> {% endfor %} </ul>
在Python 代碼中,這樣使用:
from django.urls import reverse from django.shortcuts import redirect def redirect_to_year(request): # ... year = 2006 # ... return redirect(reverse('news-year-archive', args=(year,)))
即便不一樣的APP使用相同的URL名稱,URL的命名空間模式也可讓你惟一反轉命名的URL。
命名分組 url(r'^pub/edit/(?P<pk>\d+)/$', views.publisher_edit,name='publisher_edit'), 模板中使用: {% url 'publisher'%} ——》/app01/publisher_list/ 命名分組 {% url 'publisher_edit' publisher.id %} {% url 'publisher_edit' pk=publisher.id %} 視圖中使用: from django.urls import reverse reverse('publisher') 命名分組 reverse('publisher_edit',args=(2,)) reverse('publisher_edit',kwargs={'pk':5}) 指定namespace='app01' 反向解析的時候 給name前面加上namespace ——》 namespace:name
一個視圖函數(類),簡稱視圖,是一個簡單的Python 函數(類),它接受Web請求而且返回Web響應。
Django使用請求和響應對象來經過系統傳遞狀態。
當瀏覽器向服務端請求一個頁面時,Django建立一個HttpRequest對象,該對象包含關於請求的元數據。而後,Django加載相應的視圖,將這個HttpRequest對象做爲第一個參數傳遞給視圖函數。
每一個視圖負責返回一個HttpResponse對象。
咱們以前寫過的都是基於函數的view,就叫FBV。還能夠把view寫成基於類的。 function based view.
FBV版本
# FBV版添加班級 def add_class(request): if request.method == "POST": class_name = request.POST.get("class_name") models.Classes.objects.create(name=class_name) return redirect("/class_list/") return render(request, "add_class.html")
CBV版本
# CBV版添加班級 from django.views import View class AddClass(View): def get(self, request): return render(request, "add_class.html") def post(self, request): class_name = request.POST.get("class_name") models.Classes.objects.create(name=class_name) return redirect("/class_list/") 使用CBV時,urls.py中也作對應的修改: url(r'^add_class/$', views.AddClass.as_view()),
FBV: 正常使用 給函數上加裝飾器
def wrapper(func): def inner(*args, **kwargs): start_time = time.time() ret = func(*args, **kwargs) end_time = time.time() print("used:", end_time-start_time) return ret return inner # FBV版添加班級 @wrapper def add_class(request): if request.method == "POST": class_name = request.POST.get("class_name") models.Classes.objects.create(name=class_name) return redirect("/class_list/") return render(request, "add_class.html")
使用裝飾器裝飾CBV
# CBV版添加班級 from django.views import View from django.utils.decorators import method_decorator class AddClass(View): @method_decorator(wrapper) def get(self, request): return render(request, "add_class.html") def post(self, request): class_name = request.POST.get("class_name") models.Classes.objects.create(name=class_name) return redirect("/class_list/")
裝飾器的使用:
FBV: 正常使用 給函數上加裝飾器 CBV: from django.utils.decorators import method_decorator 1. 加在方法上 @method_decorator(timer) def get(self, request): 2. 加在dispatch方法上 @method_decorator(timer) def dispatch(self, request, *args, **kwargs): 3. 加在類上 @method_decorator(timer,name='post') @method_decorator(timer,name='get') class AddPublisher(View):
CBV的流程
1. AddPublisher.as_view() ——》 view函數 2. 請求到來的時候 執行view函數 1. AddPublisher實例化 對象 ——》 self 2. self.request = request 3. 執行self.dispatch(request, *args, **kwargs) 1. 經過反射 獲取到 get post 方法 ——>handler 2. handler() ——》 得到HttpResponse對象
- 直接用裝飾器
(<app01.views.AddPublisher object at 0x0000023DE99E57B8>, <WSGIRequest: GET '/app01/pub/add/'>) <function AddPublisher.get at 0x0000023DE992ED08>
- 使用method_decorator
(<WSGIRequest: GET '/app01/pub/add/'>,) <function method_decorator.<locals>._dec.<locals>._wrapper.<locals>.bound_func at 0x0000023372154EA0>
請求相關的經常使用值
屬性
屬性: django將請求報文中的請求行、頭部信息、內容主體封裝成 HttpRequest 類中的屬性。 除了特殊說明的以外,其餘均爲只讀的。 0.HttpRequest.scheme 表示請求方案的字符串(一般爲http或https) 1.HttpRequest.body 一個字符串,表明請求報文的主體。在處理非 HTTP 形式的報文時很是有用,例如:二進制圖片、XML,Json等。 可是,若是要處理表單數據的時候,推薦仍是使用 HttpRequest.POST 。 另外,咱們還能夠用 python 的類文件方法去操做它,詳情參考 HttpRequest.read() 。 2.HttpRequest.path 一個字符串,表示請求的路徑組件(不含域名)。 例如:"/music/bands/the_beatles/" 3.HttpRequest.method 一個字符串,表示請求使用的HTTP 方法。必須使用大寫。 例如:"GET"、"POST" 4.HttpRequest.encoding 一個字符串,表示提交的數據的編碼方式(若是爲 None 則表示使用 DEFAULT_CHARSET 的設置,默認爲 'utf-8')。 這個屬性是可寫的,你能夠修改它來修改訪問表單數據使用的編碼。 接下來對屬性的任何訪問(例如從 GET 或 POST 中讀取數據)將使用新的 encoding 值。 若是你知道表單數據的編碼不是 DEFAULT_CHARSET ,則使用它。 5.HttpRequest.GET 一個相似於字典的對象,包含 HTTP GET 的全部參數。詳情請參考 QueryDict 對象。 6.HttpRequest.POST 一個相似於字典的對象,若是請求中包含表單數據,則將這些數據封裝成 QueryDict 對象。 POST 請求能夠帶有空的 POST 字典 —— 若是經過 HTTP POST 方法發送一個表單,可是表單中沒有任何的數據,QueryDict 對象依然會被建立。 所以,不該該使用 if request.POST 來檢查使用的是不是POST 方法;應該使用 if request.method == "POST" 另外:若是使用 POST 上傳文件的話,文件信息將包含在 FILES 屬性中。 7.HttpRequest.COOKIES 一個標準的Python 字典,包含全部的cookie。鍵和值都爲字符串。 8.HttpRequest.FILES 一個相似於字典的對象,包含全部的上傳文件信息。 FILES 中的每一個鍵爲<input type="file" name="" /> 中的name,值則爲對應的數據。 注意,FILES 只有在請求的方法爲POST 且提交的<form> 帶有enctype="multipart/form-data" 的狀況下才會 包含數據。不然,FILES 將爲一個空的相似於字典的對象。 9.HttpRequest.META 一個標準的Python 字典,包含全部的HTTP 首部。具體的頭部信息取決於客戶端和服務器,下面是一些示例: CONTENT_LENGTH —— 請求的正文的長度(是一個字符串)。 CONTENT_TYPE —— 請求的正文的MIME 類型。 HTTP_ACCEPT —— 響應可接收的Content-Type。 HTTP_ACCEPT_ENCODING —— 響應可接收的編碼。 HTTP_ACCEPT_LANGUAGE —— 響應可接收的語言。 HTTP_HOST —— 客服端發送的HTTP Host 頭部。 HTTP_REFERER —— Referring 頁面。 HTTP_USER_AGENT —— 客戶端的user-agent 字符串。 QUERY_STRING —— 單個字符串形式的查詢字符串(未解析過的形式)。 REMOTE_ADDR —— 客戶端的IP 地址。 REMOTE_HOST —— 客戶端的主機名。 REMOTE_USER —— 服務器認證後的用戶。 REQUEST_METHOD —— 一個字符串,例如"GET" 或"POST"。 SERVER_NAME —— 服務器的主機名。 SERVER_PORT —— 服務器的端口(是一個字符串)。 從上面能夠看到,除 CONTENT_LENGTH 和 CONTENT_TYPE 以外,請求中的任何 HTTP 首部轉換爲 META 的鍵時, 都會將全部字母大寫並將鏈接符替換爲下劃線最後加上 HTTP_ 前綴。 因此,一個叫作 X-Bender 的頭部將轉換成 META 中的 HTTP_X_BENDER 鍵。 10.HttpRequest.user 一個 AUTH_USER_MODEL 類型的對象,表示當前登陸的用戶。 若是用戶當前沒有登陸,user 將設置爲 django.contrib.auth.models.AnonymousUser 的一個實例。你能夠經過 is_authenticated() 區分它們。 例如: if request.user.is_authenticated(): # Do something for logged-in users. else: # Do something for anonymous users. user 只有當Django 啓用 AuthenticationMiddleware 中間件時纔可用。 ------------------------------------------------------------------------------------- 匿名用戶 class models.AnonymousUser django.contrib.auth.models.AnonymousUser 類實現了django.contrib.auth.models.User 接口,但具備下面幾個不一樣點: id 永遠爲None。 username 永遠爲空字符串。 get_username() 永遠返回空字符串。 is_staff 和 is_superuser 永遠爲False。 is_active 永遠爲 False。 groups 和 user_permissions 永遠爲空。 is_anonymous() 返回True 而不是False。 is_authenticated() 返回False 而不是True。 set_password()、check_password()、save() 和delete() 引起 NotImplementedError。 New in Django 1.8: 新增 AnonymousUser.get_username() 以更好地模擬 django.contrib.auth.models.User。 11.HttpRequest.session 一個既可讀又可寫的相似於字典的對象,表示當前的會話。只有當Django 啓用會話的支持時纔可用。 完整的細節參見會話的文檔。
上傳文件示例
def upload(request): """ 保存上傳文件前,數據須要存放在某個位置。默認當上傳文件小於2.5M時,django會將上傳文件的所有內容讀進內存。從內存讀取一次,寫磁盤一次。 但當上傳文件很大時,django會把上傳文件寫到臨時文件中,而後存放到系統臨時文件夾中。 :param request: :return: """ if request.method == "POST": # 從請求的FILES中獲取上傳文件的文件名,file爲頁面上type=files類型input的name屬性值 filename = request.FILES["file"].name # 在項目目錄下新建一個文件 with open(filename, "wb") as f: # 從上傳的文件對象中一點一點讀 for chunk in request.FILES["file"].chunks(): # 寫入本地文件 f.write(chunk) return HttpResponse("上傳OK") 頁面: <body> <form action="" method="post" enctype="multipart/form-data"> {% csrf_token %} <input type="file" name="file"> <button type="submit">上傳</button> </form> </body>
請求相關方法
1.HttpRequest.get_host() 根據從HTTP_X_FORWARDED_HOST(若是打開 USE_X_FORWARDED_HOST,默認爲False)和 HTTP_HOST 頭部信息返回請求的原始主機。 若是這兩個頭部沒有提供相應的值,則使用SERVER_NAME 和SERVER_PORT,在PEP 3333 中有詳細描述。 USE_X_FORWARDED_HOST:一個布爾值,用於指定是否優先使用 X-Forwarded-Host 首部,僅在代理設置了該首部的狀況下,才能夠被使用。 例如:"127.0.0.1:8000" 注意:當主機位於多個代理後面時,get_host() 方法將會失敗。除非使用中間件重寫代理的首部。 2.HttpRequest.get_full_path() 返回 path,若是能夠將加上查詢字符串。 例如:"/music/bands/the_beatles/?print=true" 3.HttpRequest.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None) 返回簽名過的Cookie 對應的值,若是簽名再也不合法則返回django.core.signing.BadSignature。 若是提供 default 參數,將不會引起異常並返回 default 的值。 可選參數salt 能夠用來對安全密鑰強力攻擊提供額外的保護。max_age 參數用於檢查Cookie 對應的時間戳以確保Cookie 的時間不會超過max_age 秒。 複製代碼 >>> request.get_signed_cookie('name') 'Tony' >>> request.get_signed_cookie('name', salt='name-salt') 'Tony' # 假設在設置cookie的時候使用的是相同的salt >>> request.get_signed_cookie('non-existing-cookie') ... KeyError: 'non-existing-cookie' # 沒有相應的鍵時觸發異常 >>> request.get_signed_cookie('non-existing-cookie', False) False >>> request.get_signed_cookie('cookie-that-was-tampered-with') ... BadSignature: ... >>> request.get_signed_cookie('name', max_age=60) ... SignatureExpired: Signature age 1677.3839159 > 60 seconds >>> request.get_signed_cookie('name', False, max_age=60) False 複製代碼 4.HttpRequest.is_secure() 若是請求時是安全的,則返回True;即請求通是過 HTTPS 發起的。 5.HttpRequest.is_ajax() 若是請求是經過XMLHttpRequest 發起的,則返回True,方法是檢查 HTTP_X_REQUESTED_WITH 相應的首部是不是字符串'XMLHttpRequest'。 大部分現代的 JavaScript 庫都會發送這個頭部。若是你編寫本身的 XMLHttpRequest 調用(在瀏覽器端),你必須手工設置這個值來讓 is_ajax() 能夠工做。 若是一個響應須要根據請求是不是經過AJAX 發起的,而且你正在使用某種形式的緩存例如Django 的 cache middleware, 你應該使用 vary_on_headers('HTTP_X_REQUESTED_WITH') 裝飾你的視圖以讓響應可以正確地緩存。
注意:鍵值對的值是多個的時候,好比checkbox類型的input標籤,select標籤,須要用:
request.POST.getlist("hobby")
HttpResponse('字符串') render(request,'html文件名',{}) 完整的頁面 redirect(地址) '/zz/' 'https://v3.bootcss.com/css/#forms' Location :'/zz/'
JSON
方法一: 後端: 在試圖函數中,return HttpResponse(json.dunps(data)),將字典轉化爲字符串。 前端: 在瀏覽器得console裏,JSON.parse('{"name":"ALEX"}'),就把字符串轉換爲對象了 方法二: from django.http import JsonResponse return sonResponse({'foo': 'bar'}),瀏覽器不用parse了。 方法三:(設置響應頭得方式) def data_json(request): data = {'name': 'alex', 'age': 73} data_list = [1, 22, 34, ] ret = HttpResponse(json.dumps(data)) ret['Content-Type'] = 'application/json' # return ret # Content-Type: text/html; charset=utf-8 return JsonResponse(data_list, safe=False) # Content-Type: application/json
注意:
JsonResponse默認只能傳遞字典類型,若是要傳遞非字典類型須要設置一下safe關鍵字參數。
response = JsonResponse([1, 2, 3], safe=False)
Django模板中只須要記兩種特殊符號: {{ }}和 {% %} {{ }}表示變量,在模板渲染的時候替換成值,{% %}表示邏輯相關的操做。
變量
view中代碼:
def template_test(request): l = [11, 22, 33] d = {"name": "alex"} class Person(object): def __init__(self, name, age): self.name = name self.age = age def dream(self): return "{} is dream...".format(self.name) Alex = Person(name="Alex", age=34) Egon = Person(name="Egon", age=9000) Eva_J = Person(name="Eva_J", age=18) person_list = [Alex, Egon, Eva_J] return render(request, "template_test.html", {"l": l, "d": d, "person_list": person_list})
模板中支持的寫法:
{# 取l中的第一個參數 #} {{ l.0 }} {# 取字典中key的值 #} {{ d.name }} {# 取對象的name屬性 #} {{ person_list.0.name }} {# .操做只能調用不帶參數的方法 #} {{ person_list.0.dream }}
注意:
注:當模板系統遇到一個(.)時,會按照以下的順序去查詢: 在字典中查詢 屬性或者方法 數字索引
Filters
翻譯爲過濾器,用來修改變量的顯示結果。
語法: {{ value|filter_name:參數 }}
'|'左右沒有空格沒有空格沒有空格
default
{{ value|default:"nothing"}} 若是value值沒傳的話就顯示nothing
filesizeformat
將值格式化爲一個 「人類可讀的」 文件尺寸 (例如 '13 KB', '4.1 MB', '102 bytes', 等等)。例如:
{{ value|filesizeformat }}
add
{{ value|add:"2" }} value是數字4,則輸出結果爲6。 {{ first|add:second }} 若是first是 [1,.2,3] ,second是 [4,5,6] ,那輸出結果是 [1,2,3,4,5,6] 。
lower
小寫 {{ value|lower }}
length
{{ value|length }} 返回value的長度,如 value=['a', 'b', 'c', 'd']的話,就顯示4.
date
日期格式化 {{ value|date:"Y-m-d H:i:s"}} 全局的配置: 在settings裏面寫: DATATIME_FORMAT = 'Y-m-d H:i:s' USE_LION = False
safe
爲了在Django中關閉HTML的自動轉義有兩種方式,若是是一個單獨的變量咱們能夠經過過濾器「|safe」的方式告訴Django這段代碼是安全的沒必要轉義。
好比: value = "<a href='#'>點我</a>" {{ value|safe}}
for循環可用的一些參數:
Variable Description forloop.counter 當前循環的索引值(從1開始) forloop.counter0 當前循環的索引值(從0開始) forloop.revcounter 當前循環的倒序索引值(從1開始) forloop.revcounter0 當前循環的倒序索引值(從0開始) forloop.first 當前循環是否是第一次循環(布爾值) forloop.last 當前循環是否是最後一次循環(布爾值) forloop.parentloop 本層循環的外層循環 須要引用外出循環的一些參數時候
for ... empty
<ul> {% for user in user_list %} <li>{{ user.name }}</li> {% empty %} <li>空空如也</li> {% endfor %} </ul> 示例: {% empty %} <tr><td colspan='4' style='text-aline:center'>沒有數據</td></tr>
csrf_token
這個標籤用於跨站請求僞造保護。 在頁面的form表單裏面寫上{% csrf_token %}
if,elif和else
{% if user_list %} 用戶人數:{{ user_list|length }} {% elif black_list %} 黑名單數:{{ black_list|length }} {% else %} 沒有用戶 {% endif %} if語句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判斷。
注意事項:
Django的模板語言不支持連續判斷,即不支持如下寫法:
{% if a > b > c %}
...
{% endif %}
繼承母版
在子頁面中在頁面最上方使用下面的語法來繼承母板。 {% extends 'layouts.html' %}
塊(block)
經過在母板中使用{% block xxx %}來定義"塊"。 在子頁面中經過定義母板中的block名來對應替換母板中相應的內容。 {% block page-main %} <p>世情薄</p> <p>人情惡</p> <p>雨送黃昏花易落</p> {% endblock %}
組件
能夠將經常使用的頁面內容如導航條,頁尾信息等組件保存在單獨的文件中,而後在須要使用的地方按以下語法導入便可。 {% include 'navbar.html' %}
靜態文件相關
- {% load static %} <link rel="stylesheet" href="{% static 'bootstrap-3.3.7/css/bootstrap.css' %}" <link rel="stylesheet" href="{% static 'css/dsb.css' %}">} <link rel="stylesheet" href="{% get_static_prefix %}bootstrap-3.3.7/css/bootstrap.css"> <link rel="stylesheet" href="{% get_static_prefix %}css/dsb.css">
經常使用字段
AutoField 自增的整形字段,必填參數primary_key=True,則成爲數據庫的主鍵。無該字段時,django自動建立。 一個model不能有兩個AutoField字段。 IntegerField 一個整數類型。數值的範圍是 -2147483648 ~ 2147483647。 CharField 字符類型,必須提供max_length參數。max_length表示字符的長度。 DateField 日期類型,日期格式爲YYYY-MM-DD,至關於Python中的datetime.date的實例。 參數: auto_now:每次修改時修改成當前日期時間。 auto_now_add:新建立對象時自動添加當前日期時間。 auto_now和auto_now_add和default參數是互斥的,不能同時設置。 DatetimeField 日期時間字段,格式爲YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],至關於Python中的datetime.datetime的實例。
字段類型
AutoField(Field) - int自增列,必須填入參數 primary_key=True BigAutoField(AutoField) - bigint自增列,必須填入參數 primary_key=True 注:當model中若是沒有自增列,則自動會建立一個列名爲id的列 from django.db import models class UserInfo(models.Model): # 自動建立一個列名爲id的且爲自增的整數列 username = models.CharField(max_length=32) class Group(models.Model): # 自定義自增列 nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) SmallIntegerField(IntegerField): - 小整數 -32768 ~ 32767 PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField) - 正小整數 0 ~ 32767 IntegerField(Field) - 整數列(有符號的) -2147483648 ~ 2147483647 PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField) - 正整數 0 ~ 2147483647 BigIntegerField(IntegerField): - 長整型(有符號的) -9223372036854775808 ~ 9223372036854775807 BooleanField(Field) - 布爾值類型 NullBooleanField(Field): - 能夠爲空的布爾值 CharField(Field) - 字符類型 - 必須提供max_length參數, max_length表示字符長度 TextField(Field) - 文本類型 EmailField(CharField): - 字符串類型,Django Admin以及ModelForm中提供驗證機制 IPAddressField(Field) - 字符串類型,Django Admin以及ModelForm中提供驗證 IPV4 機制 GenericIPAddressField(Field) - 字符串類型,Django Admin以及ModelForm中提供驗證 Ipv4和Ipv6 - 參數: protocol,用於指定Ipv4或Ipv6, 'both',"ipv4","ipv6" unpack_ipv4, 若是指定爲True,則輸入::ffff:192.0.2.1時候,可解析爲192.0.2.1,開啓此功能,須要protocol="both" URLField(CharField) - 字符串類型,Django Admin以及ModelForm中提供驗證 URL SlugField(CharField) - 字符串類型,Django Admin以及ModelForm中提供驗證支持 字母、數字、下劃線、鏈接符(減號) CommaSeparatedIntegerField(CharField) - 字符串類型,格式必須爲逗號分割的數字 UUIDField(Field) - 字符串類型,Django Admin以及ModelForm中提供對UUID格式的驗證 FilePathField(Field) - 字符串,Django Admin以及ModelForm中提供讀取文件夾下文件的功能 - 參數: path, 文件夾路徑 match=None, 正則匹配 recursive=False, 遞歸下面的文件夾 allow_files=True, 容許文件 allow_folders=False, 容許文件夾 FileField(Field) - 字符串,路徑保存在數據庫,文件上傳到指定目錄 - 參數: upload_to = "" 上傳文件的保存路徑 storage = None 存儲組件,默認django.core.files.storage.FileSystemStorage ImageField(FileField) - 字符串,路徑保存在數據庫,文件上傳到指定目錄 - 參數: upload_to = "" 上傳文件的保存路徑 storage = None 存儲組件,默認django.core.files.storage.FileSystemStorage width_field=None, 上傳圖片的高度保存的數據庫字段名(字符串) height_field=None 上傳圖片的寬度保存的數據庫字段名(字符串) DateTimeField(DateField) - 日期+時間格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] DateField(DateTimeCheckMixin, Field) - 日期格式 YYYY-MM-DD TimeField(DateTimeCheckMixin, Field) - 時間格式 HH:MM[:ss[.uuuuuu]] DurationField(Field) - 長整數,時間間隔,數據庫中按照bigint存儲,ORM中獲取的值爲datetime.timedelta類型 FloatField(Field) - 浮點型 DecimalField(Field) - 10進制小數 - 參數: max_digits,小數總長度 decimal_places,小數位長度 BinaryField(Field) - 二進制類型
字段參數
null 數據庫中字段是否能夠爲空 db_column 數據庫中字段的列名 default 數據庫中字段的默認值 primary_key 數據庫中字段是否爲主鍵 db_index 數據庫中字段是否能夠創建索引 unique 數據庫中字段是否能夠創建惟一索引
Model Meta參數
class UserInfo(models.Model): nid = models.AutoField(primary_key=True) username = models.CharField(max_length=32) class Meta: # 數據庫中生成的表名稱 默認 app名稱 + 下劃線 + 類名 db_table = "table_name" # 聯合索引 index_together = [ ("pub_date", "deadline"), # 應爲兩個存在的字段 ] # 聯合惟一索引 unique_together = (("driver", "restaurant"),) # 應爲兩個存在的字段
import os os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings") import django django.setup() from app01 import models # 獲取對象 ret = models.User.objects.get(id=1) # 獲取所全部 ——》 對象列表 ret = models.User.objects.all() # 獲取全部知足條件的對象 ——》對象列表 ret = models.User.objects.filter() # 獲取全部不知足條件的對象 ——》對象列表 ret = models.User.objects.exclude(id=1) # values ——》對象列表 {} # 不寫參數 拿全部字段name 和 value # 寫參數 拿指定字段name 和 value ret = models.User.objects.all().values('name','id') # values_list ——》對象列表 () # 不寫參數 拿全部字段value # 寫參數 拿指定字段value ret = models.User.objects.all().values_list('name','id') ret = models.User.objects.all().order_by('age','-id') ret = models.User.objects.all().order_by('id').reverse() # distinct() 去重 ret = models.User.objects.all().count() ret = models.User.objects.filter(id=100).exists() print(ret) """ 返回對象列表的方法 1. all() 2. filter() 3. exclude() 4. order_by() 5. reverse() 6. values() {} 7. values_list() () 8. distinct() 返回對象的 1. get() 2. first() 3. last() 返回布爾值 1. exists() 返回數字的 1. count() """
import os os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings") import django django.setup() from app01 import models ret = models.User.objects.filter(id__gt=1) # greater than ret = models.User.objects.filter(id__gte=1) # greater than equal ret = models.User.objects.filter(id__lt=5) # less than ret = models.User.objects.filter(id__lte=3) # less than equal ret = models.User.objects.filter(id__in=[1,3,5]) ret = models.User.objects.filter(id__range=[1,3]) ret = models.User.objects.filter(name__contains='e') # ret = models.User.objects.filter(name__icontains='e') ret = models.User.objects.filter(name__startswith='h') ret = models.User.objects.filter(birth__year='2018') ret = models.User.objects.filter(birth__month='10') ret = models.User.objects.filter(birth__day='13') print(ret)
正向查找
對象查找(跨表)
語法: 對象.關聯字段.字段 示例: book_obj = models.Book.objects.first() # 第一本書對象 print(book_obj.publisher) # 獲得這本書關聯的出版社對象 print(book_obj.publisher.name) # 獲得出版社對象的名稱
字段查找(跨表)
語法:
關聯字段__字段 示例: print(models.Book.objects.values_list("publisher__name")) 回到頂部
反向操做
對象查找
語法: obj.表名_set 示例: publisher_obj = models.Publisher.objects.first() # 找到第一個出版社對象 books = publisher_obj.book_set.all() # 找到第一個出版社出版的全部書 titles = books.values_list("title") # 找到第一個出版社出版的全部書的書名
字段查找
語法: 表名__字段 示例: titles = models.Publisher.objects.values_list("book__title")
示例:
import os os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings") import django django.setup() from app01 import models obj=models.Book.objects.get(id=1) print(obj.publisher) ret = models.Book.objects.filter(publisher__name='沙河出版社') # print(ret) pub_obj = models.Publisher.objects.get(id=14) print(pub_obj.book_set.all()) print(models.Publisher.objects.filter(book__title='九陽真經'))