總結的一些Django中會問的問題,希望對你們有用。
1、 Django的生命週期
當用戶在瀏覽器輸入url時,瀏覽器會生成請求頭和請求體發送給服務端,url經過Django中的wsgi時請求對象創建完成,經過django的中間件,然後到路由系統匹配路由,匹配成功後走到相對應的views函數,視圖函數執行相關的邏輯代碼返回執行結果,Django把客戶端想要的數據作爲一個字符串返回給客戶端,客戶端接收數據,渲染到頁面展現給用戶
2、 內置組件
Admin、from、modelfrom、model
3、 緩存方案
設置緩存到內存
緩存到redis,配置redis
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://39.96.61.39:6379",
'PASSWORD':'19990104.Yu',
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
}
}
單個view緩存
視圖導入from django.views.decorators.cache import cache_page
在需要進行緩存的視圖函數上添加如下裝飾器即可:
@cache_page(60 * 2)#20分鐘
底層緩存API
視圖導入 from django.core.cache import cache
模板片段緩存
使用cache標籤進行緩存
在HTML文件中添加:
{%load cache%}
{%cache 60 緩存名字 %}
4、 FBV和CBV
FBV:基於函數的視圖函數
CBV:基於類的視圖函數
5、 session和cookie
區別:
cookie數據存放在客戶的瀏覽器上,session數據放在服務器上
cookie不是很安全,別人可以分析存放在本地的COOKIE並進行COOKIE欺騙
考慮到安全應當使用session。
session會在一定時間內保存在服務器上。當訪問增多,會比較佔用你服務器的性能考慮到減輕服務器性能方面,應當使用COOKIE
單個cookie保存的數據不能超過4K,很多瀏覽器都限制一個站點最多保存20個cookie
建議:將登陸信息等重要信息存放爲SESSION,其他信息如果需要保留,可以放在COOKIE中
Cookie代碼
HttpCookie cookie = new HttpCookie("MyCook");//初使化並設置Cookie的名稱
DateTime dt = DateTime.Now;
TimeSpan ts = new TimeSpan(0, 0, 1, 0, 0);//過期時間爲1分鐘
cookie.Expires = dt.Add(ts);//設置過期時間
cookie.Values.Add("userid", "value");
cookie.Values.Add("userid2", "value2");
Response.AppendCookie(cookie);
6、 HTTP請求常見的方式
1、opions 返回服務器針對特定資源所支持的HTML請求方法 或web服務器發送測試服務器功能(允許客戶端查看服務器性能)
2、Get 向特定資源發出請求(請求指定頁面信息,並返回實體主體)
3、Post 向指定資源提交數據進行處理請求(提交表單、上傳文件),又可能導致新的資源的建立或原有資源的修改
4、Put 向指定資源位置上上傳其最新內容(從客戶端向服務器傳送的數據取代指定文檔的內容)
5、Head 與服務器索與get請求一致的相應,響應體不會返回,獲取包含在小消息頭中的原信息(與get請求類似,返回的響應中沒有具體內容,用於獲取報頭)
6、Delete 請求服務器刪除request-URL所標示的資源(請求服務器刪除頁面)
7、Trace 回顯服務器收到的請求,用於測試和診斷
8、Connect HTTP/1.1協議中能夠將連接改爲管道方式的代理服務器
7、 MVC和MTV模式
MTV:Model(模型):負責業務對象與數據庫的對象(ORM)
Template(模版):負責如何把頁面展示給用戶
View(視圖):負責業務邏輯,並在適當的時候調用Model和Template
MVC: 所謂MVC就是把web應用分爲模型(M),控制器(C),視圖(V)三層;他們之間以一種插件似的,松耦合的方式連接在一起。模型負責業務對象與數據庫的對象(ORM),視圖負責與用戶的交互(頁面),控制器(C)接受用戶的輸入調用模型和視圖完成用戶的請求。
8、 ORM
對象關係映射
優點:
1、ORM使得我們的通用數據庫交互變得簡單易行,並且完全不用考慮開始的SQL語句。快速開發,由此而來。
2、可以避免一些新手程序猿寫sql語句帶來的性能效率和安全問題。
缺點:
1、性能有所犧牲,不過現在的各種ORM框架都在嘗試使用各種方法來減少這個問題(LazyLoad,Cache),效果還是很顯著的。
2、對於個別的負責查詢,ORM仍然力不從心。爲了解決這個問題,ORm框架一般也提供了直接寫原生sql的方式。
9、 中間件的作用
中間件是介於request與response處理之間的一道處理過程,能在全局上改變django的輸入與輸出
10、 中間件的4種方法及應用場景(自定義中間件必須繼承MiddlewareMixin)
導包、from django.utils.deprecation import MiddlewareMixin
4種方法:
process_request
process_view
process_exception views中出現錯誤執行該方法
process_response
process_template_responseprocess 當函數中有render方法會執行該方法
11、什麼是wsgi,uwsgi,uWSGI?
WSGI:
web服務器網關接口,是一套協議。用於接收用戶請求並將請求進行初次封裝,然後將請求交給web框架
實現wsgi協議的模塊:
1.wsgiref,本質上就是編寫一個socket服務端,用於接收用戶請求(django)
2.werkzeug,本質上就是編寫一個socket服務端,用於接收用戶請求(flask)
uwsgi:
與WSGI一樣是一種通信協議,它是uWSGI服務器的獨佔協議,用於定義傳輸信息的類型
uWSGI:
是一個web服務器,實現了WSGI協議,uWSGI協議,http協議
12、ORM中的方法
1. models.Book.objects.all() # 獲取到所有的書籍對象,結果是對象列表
2. models.Book.objects.get(條件) # 獲取符合條件的對象
3. models.Book.objects.filter(條件) # 篩選所有符合條件的,結果是對象列表
4. models.Book.objects.exclude(條件) # 篩選出所有不符合條件的,結果是對象列表
5. models.Book.objects.all().values( ) # 字典列表,[ {id:1,name:20} , {id:2,name:18} ]
values(‘id’)括號內不指定時顯示全部,如指定則只顯示指定的,[ {id:1} , {id:2,} ]
6. models.Book.objects.all().values_list( ) # 元組列表,[ (1,20) , (2,18) ]同上,指定時顯示指定內容
7. models.Book.objects.all().order_by(‘id’) # 按照id升序就行排列
models.Book.objects.all().order_by(‘-id’) # 按照id降序就行排列
models.Book.objects.all().order_by(‘age’ , ‘-id’) # 先按age升序,age相同的按id進行降序排列
8. models.Book.objects.all().order_by(‘id’).reverse() # 對結果反轉; 注意reverse前必須排序,
否則reverse無效; 或在model.py文件中Book類中的Meta中指定ordering=(‘id’ , )注意逗號必須有
9. distinct(): # 去重,當獲取到的結果Queryset列表中同一對象出現多次時去重,只留一個
10. models.Book.objects.all().count() # 計數,可統計結果個數,如對Queryset內元素數進行統計.
11. models.Book.objects.all().first() # 獲取結果中的第一條,即使前面結果列表爲空,也不會報錯
12. models.Book.objects.filter().last() # 獲取結果中的最後一條
13.models.Book.objects.filter().exists() # 判斷Queryset列表是否有東西,結果爲True或False;
返回對象列表(Queryset)的方法有:
all() filter() ordey_by() exclude() values() values_list() reverse() distinct()
返回單個對象的方法有:
first() last() get() create()創建一個對象,且返回剛創建的對象
判斷布爾值的有:
exists()
返回數字的有:
count()
13、filter和exclude的區別
filter返回滿足條件的數據
exclude返回不滿足條件的數據
14、ORM中三種能寫sql語句的方法
1、execute 直接訪問數據庫,避開模型層
2、extra
3、raw for p in Person.objects.raw('SELECT * FROM myapp_person'):
print(p)
15、ORM批量處理數據
插入數據:創建一個對象列表,然後調用bulk_create方法,一次將列表中的數據插入到數據庫中。
product_list_to_insert = list()
for x in range(10):
product_list_to_insert.append(Product(name='product name ' + str(x), price=x))
Product.objects.bulk_create(product_list_to_insert)
更新數據:先進行數據過濾,然後再調用update方法進行一次性地更新
Product.objects.filter(name__contains='name').update(name='new name')
刪除數據:先是進行數據過濾,然後再調用delete方法進行一次性刪除
Product.objects.filter(name__contains='name query').delete()
16、CSRF實現機制
1)啓用中間件
2)post請求
3)驗證碼
4)表單中添加{% csrf_token%}標籤
17、Django中提供了runserver爲什麼不能用來部署項目(runserver與uWSGI的區別)
1.runserver方法是調試 Django 時經常用到的運行方式,它使用Django自帶的
WSGI Server 運行,主要在測試和開發中使用,並且 runserver 開啓的方式也是單進程 。
2.uWSGI是一個Web服務器,它實現了WSGI協議、uwsgi、http 等協議。注意uwsgi是一種通信協議,而uWSGI是實現uwsgi協議和WSGI協議的 Web 服務器。
uWSGI具有超快的性能、低內存佔用和多app管理等優點,並且搭配着Nginx就是一個生產環境了,能夠將用戶訪問請求與應用 app 隔離開,實現真正的署 。
相比來講,支持的併發量更高,方便管理多進程,發揮多核的優勢,提升性能。
18、Django中如何實現websocket
1、簡述:django實現websocket,之前django-websocket退出到3.0之後,被廢棄。官方推薦大家使用channels。
2、配置
1、需要在seting.py裏配置,將我們的channels加入INSTALLED_APP裏。
19、Django的跨域問題
1、爲什麼有跨域?
1、瀏覽器的同源策略 (從一個域上加載的腳本不允許訪問另外一個域的文檔屬性。)
2、解決跨域問題
1、前端設置代理進行訪問
2、settings中配置django-cors-headers==2.0.1
INSTALLED_APPS中添加 ‘corsheaders’
'corsheaders.middleware.CorsMiddleware',#放在session中間件下面
添加代碼
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
#允許所有的請求頭
CORS_ALLOW_HEADERS = ('*')
20、model繼承有幾種方式,分別是什麼?
抽象基類(Abstract base classes)
多表繼承(Multi-table inheritance)
Meta inheritance 當一個子類沒有聲明自己的Meta類時,它會繼承基類的 Meta 類,如果子類想擴展基類的 Meta 類 ,它可以繼承基類的Meta類,然後再進行擴展。
21、values和values_list()的區別
values : 取字典的queryset
values_list : 取元組的queryset
22、class Meta中的原信息字段有哪些?
1、app_label 應用場景:模型類不在默認的應用程序包下的models.py文件中,這時候你需要指定你這個模型類是那個應用程序的。
2、db_table 應用場景:用於指定自定義數據庫表名的
3、db_tablespace 應用場景:通過db_tablespace來指定這個模型對應的數據庫表放在哪個數據庫表空間。
4、verbose_name 應用場景:給你的模型類起一個更可讀的名字:
5、verbose_name_plural 應用場景: 模型的複數形式是什麼
6、ordering 應用場景:象返回的記錄結果集是按照哪個字段排序的
23、視圖函數中,常用的驗證裝飾器有哪些?
24、web框架的本質
socket服務端
自定製web框架
from wsgiref.simple_server import make_server
def index():
return b'index'
def login():
return b'login'
def routers():
urlpatterns = (
('/index/', index),
('/login/', login),
)
return urlpatterns
def RunServer(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/html')])
url = environ['PATH_INFO']
urlpatterns = routers()
func = None
for item in urlpatterns:
if item[0] == url:
func = item[1]
break
if func:
return [func()]
else:
return [b'404 not found']
if __name__ == '__main__':
httpd = make_server('127.0.0.1',8080,RunServer)
print("Serving HTTP on port 8080...")
httpd.serve_forever()
25、queryset的get和filter方法的區別
輸入參數:
get的參數只能是model中定義的那些字段,只支持嚴格匹配
filter的參數可以是字段,也可以是擴展的where查詢關鍵字,如in,like等
返回值:
get返回值是一個定義的model對象
filter返回值是一個新的QuerySet對象,然後可以對QuerySet在進行查詢返回新的QuerySet對象,支持鏈式操作。QuerySet一個集合對象,可使用迭代或者遍歷,切片等,但是不等於list類型
異常:
get只有一條記錄返回的時候才正常,也就說明get的查詢字段必須是主鍵或者唯一約束的字段。當返回多條記錄或者是沒有找到記錄的時候都會拋出異常。
filter有沒有匹配記錄都可以。
26、http請求的執行流程
1、域名解析
2、建立連接
3、接收請求 接收客戶端訪問某一資源的請求
單進程I/O
多進程I/O
複用I/O
4、處理請求
5、訪問資源
6、構建響應報文
7、發送響應報文
8、記錄日誌
27、如何加載初始化數據
Body中寫onload方法
Js代碼寫onload函數執行的過程
28、對Django的認知
#1.Django是走大而全的方向,它最出名的是其全自動化的管理後臺:只需要使用起ORM,做簡單的對象定義,它就能自動生成數據庫結構、以及全功能的管理後臺。
#2.Django內置的ORM跟框架內的其他模塊耦合程度高。
#應用程序必須使用Django內置的ORM,否則就不能享受到框架內提供的種種基於其ORM的便利;
#理論上可以切換掉其ORM模塊,但這就相當於要把裝修完畢的房子拆除重新裝修,倒不如一開始就去毛胚房做全新的裝修。
#3.Django的賣點是超高的開發效率,其性能擴展有限;採用Django的項目,在流量達到一定規模後,都需要對其進行重構,才能滿足性能的要求。
#4.Django適用的是中小型的網站,或者是作爲大型網站快速實現產品雛形的工具。
#5.Django模板的設計哲學是徹底的將代碼、樣式分離; Django從根本上杜絕在模板中進行編碼、處理數據的可能。
2. Django 、Flask、Tornado的對比
#1.Django走的是大而全的方向,開發效率高。它的MTV框架,自帶的ORM,admin後臺管理,自帶的sqlite數據庫和開發測試用的服務器
#給開發者提高了超高的開發效率
#2.Flask是輕量級的框架,自由,靈活,可擴展性很強,核心基於Werkzeug WSGI工具和jinja2模板引擎
#3.Tornado走的是少而精的方向,性能優越。它最出名的是異步非阻塞的設計方式
#Tornado的兩大核心模塊:
#1.iostraem:對非阻塞式的socket進行簡單的封裝
#2.ioloop:對I/O多路複用的封裝,它實現了一個單例
29、重定向的實現,用的狀態碼
1.使用HttpResponseRedirect
from django.http import HttpResponseRedirect
2.使用redirect和reverse
狀態碼:301和302 #301和302的區別:
相同點:都表示重定向,瀏覽器在拿到服務器返回的這個狀態碼後會自動跳轉到一個新的URL地址
不同點: 301比較常用的場景是使用域名跳轉。
30、nginx的正向代理與反向代理
正向代理:多臺客戶端訪問遠程資源的時候通過的是代理服務器,例如(翻牆)
反向代理:多臺客戶端訪問服務器上的資源的時候,如果用戶數量超過了服務器的最大承受限度,通過反向代理分流,把多臺客戶訪問的請求分發到不同的服務器上解決服務器壓力的問題
31、路由系統中name的作用
用於反向解析路由,相當於給url取個別名,只要這個名字不變,即使對應的url改變 通過該名字也能找到該條url
32、select_related和prefetch_related的區別?
有外鍵存在時,可以很好的減少數據庫請求的次數,提高性能
#select_related通過多表join關聯查詢,一次性獲得所有數據,只執行一次SQL查詢
#prefetch_related分別查詢每個表,然後根據它們之間的關係進行處理,執行兩次查詢
33、django orm 中如何設置讀寫分離?
1.手動讀寫分離:通過.using(db_name)來指定要使用的數據庫
2.自動讀寫分離:
1.定義類:如Router #
2.配置Router settings.py中指定DATABASE_ROUTERS
DATABASE_ROUTERS = ['myrouter.Router',]
34、django中如何根據數據庫表生成model中的類?
1.在settings中設置要連接的數據庫
2.生成model模型文件
python manage.py inspectdb
3.模型文件導入到models中
python manage.py inspectdb > app/models.py
35、什麼是RPC
遠程過程調用 (RPC) 是一種協議,程序可使用這種協議向網絡中的另一臺計算機上的程序請求服務
1.RPC採用客戶機/服務器模式。請求程序就是一個客戶機,而服務提供程序就是一個服務器。
2.首先,客戶機調用進程發送一個有進程參數的調用信息到服務進程,然後等待應答信息。 2.在服務器端,進程保持睡眠狀態直到調用信息到達爲止。當一個調用信息到達,服務器獲得進程參數,計算結果,發送答覆信息,然後等待下一個調用信息,
3.最後,客戶端調用進程接收答覆信息,獲得進程結果,然後調用執行繼續進行。
36、如何實現用戶的登錄認證
1.cookie session
2.token 登陸成功後生成加密字符串
3.JWT:json wed token縮寫 它將用戶信息加密到token中,服務器不保存任何用戶信息 #服務器通過使用保存的密鑰來驗證token的正確性
37、抽象繼承
38、is_valid()的用法
檢查對象變量是否已經實例化即實例變量的值是否是個有效的對象句柄
39、取消級聯刪除
40、pv和uv
1.pv:頁面訪問量,沒打開一次頁面PV計算+1,頁面刷新也是
#2.UV:獨立訪問數,一臺電腦終端爲一個訪客
41、django rest framework框架中都有那些組件?
1.序列化組件:serializers 對queryset序列化以及對請求數據格式校驗
2.認證組件 寫一個類並註冊到認證類(authentication_classes),在類的的authticate方法中編寫認證邏
3.權限組件 寫一個類並註冊到權限類(permission_classes),在類的的has_permission方法中編寫認證邏輯
4.頻率限制 寫一個類並註冊到頻率類(throttle_classes),在類的的allow_request/wait 方法中編寫認證邏輯
5.渲染器 定義數據如何渲染到到頁面上,在渲染器類中註冊(renderer_classes)
6.分頁 對獲取到的數據進行分頁處理, pagination_class
42、使用orm和原生sql的優缺點?
1.orm的開發速度快,操作簡單。使開發更加對象化 #執行速度慢。處理多表聯查等複雜操作時,ORM的語法會變得複雜
2.sql開發速度慢,執行速度快。性能強
43、F和Q的作用?
F:對數據本身的不同字段進行操作 如:比較和更新
Q:用於構造複雜的查詢條件 如:& |操作