http協議: ( 基於TCP/IP通訊協議來傳遞數據(HTML 文件, 圖片文件, 查詢結果等)) HTTP協議是Hyper Text Transfer Protocol(超文本傳輸協議)的縮寫, 是用於從萬維網(WWW:World Wide Web) 服務器傳輸超文本到本地瀏覽器的傳送協議
HTTP是無鏈接:無鏈接的含義是限制每次鏈接只處理一個請求。服務器處理完客戶的請求,並收到客戶的應答後,即斷開鏈接。 採用這種方式能夠節省傳輸時間。 HTTP是媒體獨立的:這意味着,只要客戶端和服務器知道如何處理的數據內容,任何類型的數據均可以經過HTTP發送。客戶端 以及服務器指定使用適合的MIME-type內容類型。 HTTP是無狀態:HTTP協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。缺乏狀態意味着若是後續處理須要前面 的信息,則它必須重傳,這樣可能致使每次鏈接傳送的數據量增大。另外一方面,在服務器不須要先前信息時它的應答就較快
請求頭 | 釋義 | 例子 |
---|---|---|
Accept | 指定客戶端可以接收的內容類型 | Accept : text / plain / text / html |
Cache-Control | 指定請求和響應遵循的緩存機制 | Cache-Control : no-cache |
Cookie | HTTP請求發送時,會把保存在該請求域名下的全部cookie值一塊兒發送給web服務器 | Cookie: $Version=1; Skin=new; |
Content-Type | 請求的與實體對應的MIME信息 | Content-Type: application / x-www-form-urlencoded |
Host | 指定請求的服務器的域名和端口號 | 0.0.0.0 |
Referer | 先前網頁的地址,當前請求網頁緊隨其後,即來路 | -www.zhihu-com |
User-Agent | 發起請求的用戶的身份標識 |
GET:請求指定的頁面信息,並返回實體主體 HEAD:相似於get請求,只不過返回的響應中沒有具體內容,用於獲取報頭 POST:向指定的資源提交數據進行請求處理,數據被包含在請求體中,POST請求可能致使新的資源的創建或已有資源的修改 put:從客戶端向服務器傳送的數據取代指定的文檔的內容 DELETE:請求服務器刪除指定的內容 CONNECT:Http/1.1 協議中預留給能將鏈接改成管道方式的代理服務器 OPTIONS:容許客戶端查看服務器的性能 TRACE:回顯服務器收到的請求,主要用於測試和診斷
1xx:指示信息–表示請求已接收,繼續處理。 2xx:成功–表示請求已被成功接收、理解、接受。 3xx:重定向–要完成請求必須進行更進一步的操做。 4xx:客戶端錯誤–請求有語法錯誤或請求沒法實現。 5xx:服務器端錯誤–服務器未能實現合法的請求
200 OK :客戶端請求成功,通常用於GET和POST請求 400 Bad Request:客戶端請求有語法錯誤,不能被服務器所理解。 301 Moved Permanently:永久移動,請求的資源已被永久移動到新url,返回信息會包含新的url,瀏覽器會自動定向到 新url 401 Unauthorized :請求未經受權,這個狀態代碼必須和WWW-Authenticate報頭域一塊兒使用。 403 Forbidden :服務器收到請求,可是拒絕提供服務。 404 Not Found :請求資源不存在,舉個例子:輸入了錯誤的URL。 500 Internal Server Error :服務器發生不可預期的錯誤。 502 Bad Gateway : 充當網關或代理的服務器,從遠端接收到一個無效的請求 503 Server Unavailable:服務器當前不能處理客戶端的請求,一段時間後可能恢復正常
http : 超文本傳輸協議, 明文傳輸80端口 鏈接簡單且是無狀態的 https: 須要到ca申請證書, 要費用 具備安全性的ssl加密傳輸協議 端口是443 https協議是有ssl+http協議構建的可進行加密傳輸,身份認證的網絡協議,安全
WebSocket是HTML5開始提供的一種在單個TCP鏈接上進行全雙工通信的協議。 在WebSocket API中,瀏覽器和服務器只須要完成一次握手,二者之間就直接能夠建立持久性的鏈接,並進行雙向數據傳輸。 舊--不少網站爲了實現推送技術,所用的技術都是 Ajax 輪詢。輪詢是在特定的的時間間隔(如每1秒),由瀏覽器對服務器發出HTTP請求,而後由服務器返回最新的數據給客戶端的瀏覽器。這種傳統的模式帶來很明顯的缺點,即瀏覽器須要不斷的向服務器發出請求,然而HTTP請求可能包含較長的頭部,其中真正有效的數據可能只是很小的一部分,顯然這樣會浪費不少的帶寬等資源。 新---HTML5定義的WebSocket協議,能更好的節省服務器資源和帶寬,而且可以更實時地進行通信。瀏覽器經過 JavaScript 向服務器發出創建WebSocket鏈接的請求,鏈接創建之後,客戶端和服務器端就能夠經過TCP鏈接直接交換數據。
django實現websocket大體上有兩種方式,一種channels,一種是dwebsocket。channels依賴於redis,twisted等,相比之下使用dwebsocket要更爲方便一些。 安裝: pip install dwebsocket 配置: # setting.py INSTALLED_APPS = [ ..….. ..….. ‘dwebsocket’, ] MIDDLEWARE_CLASSES = [ ..…..… ..…..… ‘dwebsocket.middleware.WebSocketMiddleware’ # 爲全部的URL提供websocket,若是隻是單獨的視圖須要能夠不選 ] WEBSOCKET_ACCEPT_ALL=True # 能夠容許每個單獨的視圖實用websockets
簡單使用:
模擬文件下載的簡單示例html
from dwebsocket.decorators import accept_websocket @accept_websocket def test(request): if not request.is_websocket(): # 判斷是否是websocket鏈接 return render(request, 'websocket.html') else: download = Haproxy() t = threading.Thread(target=download.run) t.start() sent = [] while download.status: if len(download.res_dict) > len(sent): for i in download.res_dict.keys(): if i not in sent: sent.append(i) request.websocket.send(str(sent[-1]+str(download.res_dict[sent[-1]])).encode('utf-8')) # 發送消息到客戶端 if not download.status: request.websocket.send('下載完成'.encode('utf-8'))
效果圖:前端
詳細:python
dwebsocket
有兩種裝飾器:require_websocket
和accept_websocekt
,使用require_websocket
裝飾器會致使視圖函數沒法接收致使正常的http
請求,通常狀況使用accept_websocket
方式就能夠了,jquery
dwebsocket
的一些內置方法:nginx
request.is_websocket()
:判斷請求是不是websocket
方式,是返回true
,不然返回false
request.websocket
: 當請求爲websocket
的時候,會在request
中增長一個websocket
屬性,WebSocket.wait()
返回客戶端發送的一條消息,沒有收到消息則會致使阻塞WebSocket.read()
和wait
同樣能夠接受返回的消息,只是這種是非阻塞的,沒有消息返回None
WebSocket.count_messages()
返回消息的數量WebSocket.has_messages()
返回是否有新的消息過來WebSocket.send(message)
像客戶端發送消息,message
爲byte
類型使用JSONP Web頁面上調用js的script腳本文件不受跨域影響 建立一個回調函數,而後在遠程服務上調用這個函數而且將JSON 數據形式做爲參數傳遞,完成回調 jquery中可使用jquery提供的getJSON方法來發送JSONP請求獲取數據 (隨機產生一個函數名隨請求送到服務 器,服務器將JSON數據填充進回調函數,JSONP請求結束後執行回調函數) 缺點: 先後端都要支持,只能發個get請求 CORS解決跨域 處理簡單請求: 只須要在返回的響應頭中加上 Access-Control-Allow-Origin 字段.而且把該字段的值設置爲 跨域請求的來源地址或簡單的設置爲 * 處理非簡單請求:自定義一箇中間件,在後端簡單的給響應對象添加上 經常使用請求方法(PUT、DELETE)的支持 from django.utils.deprecation import MiddlewareMixin class CorsMiddleware(MiddlewareMixin): def process_response(self, request, response): # 給響應頭加上 Access-Control-Allow-Origin 字段 並簡單的設置爲 * response['Access-Control-Allow-Origin'] = '*' if request.method == 'OPTIONS': # 容許發送 PUT 請求 response['Access-Control-Allow-Methods'] = 'PUT, DELETE' # 容許在請求頭中攜帶 Content-type字段,從而支持發送json數據 response['Access-Control-Allow-Headers'] = 'Content-type' return response
CORS
解決方案,使用django-cors-headers
已封裝, 在settings
文件中進行相關配置web
強制緩存,服務器通知瀏覽器一個緩存時間,在緩存時間內,下次請求,直接用緩存,不在時間內,執行比較緩存策略。 比較緩存,將緩存信息中的Etag和Last-Modified經過請求發送給服務器,由服務器校驗,返回304狀態碼時,瀏覽器直接使用緩存。
Django Flask Toenado
wsgi server (好比uWSGI) 要和 wsgi application(好比django )交互,uwsgi須要將過來的請求轉給django處理,那麼 uWSGI 和 django 的交互和調用就須要一個統一的規範,這個規範就是WSGI WSGI(Web Server Gateway Interface) WSGI --- 全稱 Web Server Gateway Interface,或者 Python Web Server Gateway Interface ,是爲 Python 語言定義的 Web 服務器和 Web 應用程序或框架之間的一種簡單而通用的接口 WSGI 的官方定義是,the Python Web Server Gateway Interface。從名字就能夠看出來,這東西是一個 Gateway,也就是網關。網關的做用就是在協議之間進行轉換 WSGI 是做爲 Web 服務器與 Web 應用程序或應用框架之間的一種低級別的接口
緩存是將一個或某個views的返回值保存至內存或者memcache等中,必定時間後當再有人來訪問時候,則再也不去執行view中的操做,而是直接從內存或者redis中以前緩存的內容拿到,並返回 django中的6種緩存機制 開發調試 內存文件數據庫 Memcache緩存(python-memcached模塊) Memcache緩存(pylibmc模塊) 另外: 基於redis實現的緩存 應用方面: 全站應用 單獨視圖的緩存 局部視圖的應用
Django 信號 pre_save,預處理 models 若是一個 models 在保存到數據庫以前,咱們須要對存入數據進行預處理,這時候咱們就須要pre_save。 pre_save 和 post_save 相似於 React 的生命週期,是針對 Django models 在保存(save())先後的鉤子(hook),這兩個方法可讓咱們在 models 的保存先後,對數據或者其餘內容進行一些處理。而這種鉤子函數,在 Django 中被稱之爲 signal(信號)。 SlugField 構建語義化 url SlugField 本質上至關於存放字符串,可是在乎義上,主要用於把某些字段造成語義化的,能夠訪問的短網址(slug)字符串。
舉例而言,假設有一個關於文章的 models,有兩個字段,分別是標題 title 和短網址 slug。ajax
class Article(models.Model): title = models.CharField(max_length=100) slug = models.SlugField(max_length=40)
這時候存入models
的一條信息,title 是 The song of ice and fire
。若是咱們想用文章的標題做爲 url
進行訪問,完整的標題多是:redis
www.xxx.com/article/The song of ice and fire
可是url
是不能出現空格的,所以空格會被轉變成%20
,最後網址獲得sql
www.xxx.com/article/The%20song%20of%20ice%20and%20fire
咱們不但願出現這麼多難看的%20
,而是但願用短橫線 - 替代空格,獲得數據庫
www.xxx.com/article/the-song-of-ice-and-fire
而Django
的django.utils.text
提供了一個方法叫slugify
,能夠把剛纔的文章標題The song of ice and fire
作兩個轉變:
由於這種轉變主要用於作url
拼接,因此咱們把這種結果都統一放在SlugField
字段裏面,用以構建語義化的url
網址。
pre_save
+ slugify
構建SlugField
完整的代碼以下示例:
slug
是惟一的字段,不能出現重複slug
,因此 SlugField
的屬性是 unique=True
pre_save.connect(pre_save_post_receiver, sender=Post)
把Post
這個 models
以及自定義的處理函數pre_save_post_receiver
鏈接起來,表示在 Post
存儲以前,先用該函數進行數據預處理。slug
,若是沒有slug
,就把標題 title
用 slugify
轉化成 slug
slug
,就把以前的 slug
對應的數據的id
拿過來,拼接在本次 slug
的後面。固然也能夠用其餘方法進行區分,避免重複。在models.py
from django.db import models from django.db.models.signals import pre_save from django.utils.text import slugify class Post(models.Model): # ... title = models.CharField(max_length=150) slug = models.SlugField(unique=True) def create_slug(instance): slug = slugify(instance.title) qs = Post.objects.filter(slug=slug).order_by("-id") exists = qs.exists() if exists: new_slug = "{0}-{1}".format(slug, qs.first().id) return new_slug return slug def pre_save_post_receiver(sender, instance, *args, **kwargs): if not instance.slug: instance.slug = create_slug(instance) pre_save.connect(pre_save_post_receiver, sender=Post)
Nginx+uwsgi nginx做爲服務器最前端,負責接收client的全部請求,統一管理。靜態請求由Nginx本身處理。 非靜態請求經過uwsgi傳遞給Django,由Django來進行處理,從而完成一次WEB請求
user = Users.objects.order_by(‘id’) user = Users.objects.order_by(‘id’)[0:1] # 若是須要逆序 在字段前加負號 例 (‘-id’)
優勢 : Memcached是Django原生支持的緩存系統,速度快,效率高 缺點 : 基於內存的緩存系統有個明顯的缺點就是斷電數據丟失
User.objects.filter().exclude(id=5) # 查詢id不爲5的用戶
select * from company where title like "%abc%" or mecount>999 order by createtime desc; # desc表示的是降序 objects.filter(Q(title__contains='abc')|Q(mecount__gh=999)).order_by(-createtime)
http://www.baidu.com
到頁面返回, 中間都是發生了什麼 ?1. 瀏覽器向 DNS 服務器請求解析該 URL中的域名所對應的 IP 地址; 2. 解析出 IP 地址後,根據該 IP 地址和默認端口 80,和服務器創建TCP鏈接; 3. 瀏覽器發出讀取文件(URL中域名後面部分對應的文件)的HTTP 請求,該請求報文做爲 TCP 三次握手的 第三個報文的數據發送給服務器 4. 服務器對瀏覽器請求做出響應,並把對應的 html 文本發送給瀏覽器; 5. 釋放 TCP鏈接,四次揮手; 6. 瀏覽器將該 html 文本並顯示內容;
1.19 Django請求的生命週期
wsgi
—> 中間件 —> 路由 -–-–> 視圖 —> 中間件 —> wsgi
經過Django中的信號去實現
中間件的概述: 中間件是一個輕量,低級別的的插件系統,用於在全局範圍內改變django的輸入和輸出,實際做用就是在視圖函數之執行以前後執行 以後作一些額外的操做。本質上是一個自定義類,類中定義幾個方法,Django框架會在處理請求的特定的時間去執行這些方法 應用場景: 1. django項目中默認啓用了csrf保護,每次請求時經過CSRF中間件檢查請求中是否有正確的token值 2. 當用戶在頁面上發送請求時,經過自定義的認證中間件,判斷用戶是否已登陸,未登陸跳轉登陸頁面 3. 當有用戶請求過來時,判斷用戶是否在白名單或者在黑名單裏非同源策略中跨域問題,使用CORS解決跨域問題時候,須要本身定義中間件或者使用 django-cors-headers須要 在中間中進行配置 4. 當要全站使用緩存的情形,須要在中間件中進行配置 ..........
FBV:function base view 函數處理請求 經過在view.py裏面定義一個函數,而後經過函數的request參數獲取method的類型,而後根據提交的不一樣方式進 行不一樣的處理。 CBV:class base view 類處理請求 經過自定義一個子類繼承這個類,咱們能夠利用View裏面的dispatch()方法來判斷請求是get仍是post。 dispatch方法的本質是一個反射器,能夠根據名字來調用同名的方法 注:子類裏面能夠從新定義了dispatch這個方法,同時使用super()來調用父類的構造方法,這樣的好處是功能不變,可是能夠靈活的添加新的功能 class Login(View): def dispatch(self, request, *args, **kwargs): print('before') obj = super(Login,self).dispatch(request, *args, **kwargs) print('after') return obj
from django.utils.decorators import method_decorator #將裝飾器加在某個get/post的方法上 @method_decorator(xxx) def get(self, request): pass
#將裝飾器加在本身定義的的dispatch方法上 @method_decorator(xxx) def dispatch(self, request, *args, **kwargs): pass
@method_decorator(xxx, name='post') @method_decorator(xxx, name='get') class AddPublisher(View): pass
# 或者能夠在url上加裝飾器 -- 會爲類視圖中的全部請求方法都加上裝飾器行爲 urlpatterns = [ url(r'^demo/$', xxx(DemoView.as_view())) ]
多個數據庫
python manage.py makemigrations
python manage.py migrate -- database db2 //settings
配置多個數據庫
讀寫分離
s = models.Student.objects.using('default').all() models.Student.objects.using('db2').create(name='xxx',)
# myrouter class Router: def db_for_read(self, model, **kwargs): return 'default' def db_for_write(self, model, **kwargs): return 'db2'
settings
中配置
DATABASE_ROUTERS = ['myrouter.Router']
一主多從
# 一主多從 import random class Router: def db_for_read(self, model, **kwargs): return random.choices(['db1', 'db2', 'db3']) def db_for_write(self, model, **kwargs): return 'db'
分庫分表
# 分庫分表 # app01 db1 app02 db2 class Router: def db_for_read(self, model, **kwargs): if model._meta.app_label == 'app01': return 'db1 ' elif model._meta.app_label == 'app02': return 'db2' def db_for_write(self, model, **kwargs): if model._meta.app_label == 'app01': return 'db1 ' elif model._meta.app_label == 'app02': return 'db2'
---------必知必會13條---------- # 獲取對象列表 all() -- 獲取全部數據 (對象列表) filter() -- 獲取知足條件的全部對象(對象列表)# 獲取一個對象,沒有或者是多個的時候會報錯 exclude() -- 獲取不知足條件的全部對象 (對象列表) values() -- 獲取對象的字段名和值 values_list() -- 獲取對象的值 order_by() -- 排序,默認升序,加 - 降序 (指定多個排序,按第一個升序,遇到相同時候再使用第二個) reverse() -- 給已經排好序的結果倒敘排序 --> 前提是得使用order_by後 distinct() -- 會對徹底相同的內容去重(但不是某一字段相同就去重) # 獲取對象: get() first() -- 取第一個 last() -- 最後一個 # 數字 count() -- 計數 # 布爾值 exists() -- 判斷是否存在,返回bool
---------單表雙下劃線---------- __gt 大於 __gte 大於等於 __lt 小於 __lte 小於等於 __isnull 爲空 __in =[ ] 在列表中的全部對象 __range=[1,10] 字段值的範圍,左右都包含 __contains 包含某一字母 __icontains 大小寫都會包含 __startswith 以..開頭 __istartswith 以..開頭,忽略大小寫 __endswith 以..結尾 __isendswith 以..結尾,忽略大小寫
# ---------外鍵操做---------- # 描述多對一的關係 class Publisher(models.Model): name = models.CharField(max_length=32) class Book(models.Model): publisher=models.ForeignKey( 'Publisher', on_delete=models.CASCADE, related_name='books ) # --------------------------- # 基於對象的查詢 # 正向查詢 -> 有外鍵的一側,查關聯對象 book_obj = models.Book.objects.get(id =1) # book_obj.publisher -> 關聯的對象 # book_obj.publisher_id -> 關聯對象的id # book_obj.publisher.id -> 關聯對象的id # 反向查詢 被關聯對象,查有外鍵的一側 publiser_obj = models.Publisher.objects.get(id=1) # publisher_obj.book_set -> 管理對象 (全部書籍) # publisher_obj.book_set.all() -> 出版社所管理的全部書籍對象 (全部書籍) # 另外:當指定 relate_name = books" publisher_obj.books ->管理對象 (全部書籍) # 基於字段的查詢 models.Book.objects.filter(publisher__name ='xxxx')
#---------多對多---------- 方式一 class Author(): name = models.CharField(max_length=32) books = models.ManyToManyField('Book') 方式二 class Author(models.Model): name = models.CharField(max_length=32) class Author_Book(models.Model): author = models.ForeignKey('Author') book = models.ForeignKey('Book') date = models.DateTimeField() 方式三 class Author(models.Model): name = models.CharField(max_length=32) books = models.ManyToManyField('Book', through='Author_Book') class Author_Book(models.Model): author = models.ForeignKey('Author') book = models.ForeignKey('Book') date = models.DateTimeField() # ----------- 查詢方法 -------------- # 基於對象的查詢 # 正向查詢: author_obj = models.Author.objects.get(id=2) # author_obj.books -—> 管理對象 # author_obj.books.all() --> 該做者寫的全部書籍對象 # 反向查詢 book_obj = models.Book.objects.get(id=2) # 不指定 related_name ='authors' # print(book_obj.author_set.all()) # 指定related_name ='authors' # print(book_obj.authors.all()) ##[<Author: Author object>, <Author: Author object>]> 由於做者沒有定義str方法## # --------------- 其餘方法 ------------ # set 設置多對多關係 # 所有從新設置id= 2 的三條數據所有清空 author_obj.books.set([]) author_obj.books.set([1,2]) # y要關聯對象的id (就是給id爲1和id爲2 的兩本書設置多對多) # add 添加對對多關係 author_obj.books.add(3) # 要關聯對象的id author_obj.books.add(models.Book.objects.get(id=3))# 要關聯的對象 # remove 刪除多對多的關係 author_obj.books.remove(3) # 要關聯對象的id author_obj.books.remove(models.Book.objects.get (id=2)) # 要關聯的對象 # clear() # 清空當前(id=2也就是author_obj對象)的多對多的關係 author_obj.books.clear() # create() author_obj.books.create(title='楚留香傳奇') book_obj.authors.create(name='古龍2')
F
的做用 ?from django.db.models import F # 動態獲取字段的值, 能夠在一條記錄中比較兩個字段的value # 查詢庫存大於50的書籍 ret = models.Book.objects.filter(store__gt=50).values() # for i in ret: # print(i) # 第一種用法,動態的獲取想要獲取的字段 (能夠比較兩列的值) # 獲取庫存大於售出的書籍 ret2 = models.Book.objects.filter(store__gt=F('sale')).values() for i in ret2: print(i) # 第二種用法 (使用update更新) # 庫存不變時候,售出數量乘2 models.Book.objects.all().update(sale=F('sale')*2) # 注: update 和更新後使用save的區別 # update 它能夠更新指定字段,能夠是多個, 然後者會將全部的字段作更新
Q
的做用 ?from django.db.models import Q ret = models.Book.objects.filter(Q(~Q(id__lt=3) | Q(id__gt=5))&Q(id__lt=4)) print(ret) # ~ 取反 # | 或 # & 與 AND
在Django中使用原生Sql主要有如下幾種方式: extra:結果集修改器,一種提供額外查詢參數的機制(依賴model) raw:執行原始sql並返回模型實例(依賴model) 直接執行自定義sql(不依賴model)
# -------使用extra -------- Book.objects.filter(publisher__name='廣東人員出版社').extra(where=['price>50']) Book.objects.filter(publisher__name='廣東人員出版社',price__gt=50) Book.objects.extra(select={'count':'select count(*) from hello_Book'})
#---------使用raw ---------- Book.objects.raw('select * from hello_Book') Book.objects.raw("insert into hello_author(name) values('測試')") rawQuerySet爲惰性查詢,只有在使用時生會真正執行
#--------自定義查詢 ---------- 執行自定義sql: from django.db import connection cursor=connection.cursor() # 插入操做 cursor.execute("insert into hello_author(name) values('郭敬明')") # 更新操做 cursor.execute('update hello_author set name='abc' where name='bcd'') # 刪除操做 cursor.execute('delete from hello_author where name='abc'') # 查詢操做 cursor.execute('select * from hello_author') raw=cursor.fetchone() # 返回結果行遊標直讀向前,讀取一條 cursor.fetchall() # 讀取全部
only(field) : 定義須要的字段 (id保留) defer(field): 排除不須要的字段 (id保留)
在數據庫有外鍵的時候,使用select_related()和prefetch_related()能夠很好的減小數據庫請求的次數,從而提升性能. select_related() 對於一對一字段(OneToOneField)和外鍵字段(ForeignKey),可使用select_related()來QuerySet進行優化.在對QuerySet使用select_related()函數後,Django會獲取相應外鍵對應的對象,從而在以後須要的時候沒必要再查詢數據庫了。 select_related經過多表join關聯查詢,一次性得到全部數據,只執行一次SQL查詢 prefetch_related分別查詢每一個表,而後根據它們之間的關係進行處理,執行兩次查詢
values 字典列表,ValuesQuerySet查詢集 <QuerySet [ {'id': 2, 'name': '做者2', 'age': 24}, {'id': 3, 'name': '做者3', 'age': 35}] > values_list 返回元祖列表,字段值 <QuerySet [ (2, '做者2', 24), (3, '做者3', 35)] >
objs_list = [] for i in range(100): obj = People('name%s'%i,18) # models裏面的People表 objs_list.append(obj) # 添加對象到列表 People.objects.bulk_create(objs_list,100) # 更新操做
form 生成頁面可用的HTML標籤 | 對用戶提交的數據進行校驗 | 保留上次輸入內容 Model Form 利用 Django 的 ORM 模型model建立Form(表單跟model關係密切)
在使用選擇標籤時,須要注意choices的選項能夠從數據庫中獲取,可是因爲是靜態字段獲取的值沒法實時更新,那麼須要自定義構造方法從而達到此目的。
# 重寫構造函數 from django.forms import Form from django.forms import widgets from django.forms import fields class MyForm(Form): user = fields.ChoiceField( # choices=((1, '上海'), (2, '北京'),), initial=2, widget=widgets.Select) def __init__(self, *args, **kwargs): super(MyForm,self).__init__(*args, **kwargs) # self.fields['user'].choices = ((1, '上海'), (2, '北京'),) # 或 self.fields['user'].choicesmodels.Classes.objects.all().values_list('id','caption') # 利用ModelChoiceField字段,參數爲queryset對象 from django import forms from django.forms import fields from django.forms import models as form_model class FInfo(forms.Form): authors = form_model.ModelMultipleChoiceField(queryset=models.NNewType.objects.all()) # 多選 # authors = form_model.ModelChoiceField(queryset=models.NNewType.objects.all()) # 單選
class Author(models.Model): author = models.CharField(max_length=250) class Books(models.Model): book = models.ForeignKey(Author,on_delete=models.CASCADE) # CASCADE:刪除做者信息一併刪除做者名下的全部書的信息; # PROTECT:刪除做者的信息時,採起保護機制,拋出錯誤:即不刪除Books的內容 # SET_NULL:只有當null=True纔將關聯的內容置空; # SET_DEFAULT:設置爲默認值; # SET():括號裏能夠是函數,設置爲本身定義的東西; # DO_NOTHING:字面的意思,啥也不幹,你刪除你的幹我毛線
第一步:django第一次響應來自某個客戶端的請求時,後端隨機產生一個token值,把這個token保存在SESSION狀態中;同時,後端把這個token放到cookie中交給前端頁面; 第二步:下次前端須要發起請求(好比發帖)的時候把這個token值加入到請求數據或者頭信息中,一塊兒傳給後端;Cookies: {csrftoken:xxxxx} 第三步:後端校驗前端請求帶過來的token和SESSION裏的token是否一致。
// 在HTML頁面中使用 {% csrf_token %},給POST提交數據中添加 csrfmiddlewaretoken的鍵值對 data :{ 'csrfmiddlewaretoken':$('[name="csrfmiddlewaretoken"]').val(), i1:$('[name="i1"]').val(), i2:$('[name="i2"]').val() },
// 在HTML頁面中使用 {% csrf_token %},在ajax中添加X-csrftoken的請求頭 headers:{ 'X-csrftoken': $('[name="csrfmiddlewaretoken"]').val(), },
依賴:pip3 install django-redis from django_redis import get_redis_connection conn = get_redis_connection("default")
url的命名:用於反向解析 # 以命名user_list爲例 url(r'/user_list/',view,name='user_list') from django.urls import reverse reverse('user_list') ——> '/app01/user_list/' # 模板中使用 {% url 'user_list' %} ——> '/app01/user_list/' url(r'/edit_user/(\d+)',view,name='edit_user') reverse('edit_user',args=('1',)) ——> '/edit_user/1/' {% url 'edit_user' 1 %} ——> '/edit_user/1/' url(r'/edit_user/(?P<pk>\d+)',view,name='edit_user') reverse('edit_user',args=('1',)) ——> '/edit_user/1/' {% url 'edit_user' 1 %} ——>'/edit_user/1/' reverse('edit_user',kwargs={'pk':2} ——> '/edit_user/2/' {% url 'edit_user' pk=1 %} ——> '/edit_user/1/'
from django import template register = template.Library()
@register.filter def addxx(value,arg=None): return 'xxxxx' @register.simple_tag def simple(*args,**kwargs): return 'cccccc' @register.inclusion_tag('li.html') def show_li(*args,**kwargs): return {'k1':v1}
{% load my_tags %} {{ 'alex'|addxx:'sb' }} {% simple 'v1' 'v2' k1='v3' %} {% show_li %}
orm
中db first
和code first
的含義 ?db first: 先建立數據庫,再更新表模型 code first:先寫表模型,再更新數據庫
一、修改seting文件,在setting裏面設置要鏈接的數據庫類型和名稱、地址 二、運行下面代碼能夠自動生成models模型文件 - python manage.py inspectdb 三、建立一個app執行下下面代碼: - python manage.py inspectdb > app/models.py
SQL: 優勢:執行速度快 缺點:編寫複雜,開發效率不高 ---------------------------------- ORM: 優勢:讓用戶再也不寫SQL語句,提升開發效率 能夠很方便地引入數據緩存之類的附加功能 缺點:在處理多表聯查、where條件複雜查詢時,ORM的語法會變得複雜。沒有原生SQL速度快
MVC,全名是Model View Controller,是軟件工程中的一種軟件架構模式,把軟件系統分爲三個基本部分: 模型(Model) -- 存取數據 視圖(View) -- 信息展現 控制器(Controller) -- 邏輯的控制 具備耦合性低、重用性高、生命週期成本低等優勢 Django框架的設計模式借鑑了MVC框架的思想,也是分紅三部分,來下降各個部分之間的耦合性。 Django框架的不一樣之處在於它拆分的三部分爲:Model(模型)、Template(模板)和View(視圖),也就是MTV框架 Model(模型):負責業務對象與數據庫的對象(ORM) Template(模版):負責如何把頁面展現給用戶 View(視圖):負責業務邏輯,並在適當的時候調用Model和Template 此外,Django還有一個urls分發器,它的做用是將一個個URL的頁面請求分發給不一樣的view處理,view再調用相應的Model和 Template
contenttype是django的一個組件(app),它能夠將django下全部app下的表記錄下來 可使用他再加上表中的兩個字段,實現一張表和N張表動態建立FK關係。 - 字段:表名稱 - 字段:數據行ID 應用:路飛表結構優惠券和專題課和學位課關聯