1. 程式人生 > 其它 >.NET Core基礎掃盲

.NET Core基礎掃盲

django檢視層

虛擬環境

# 針對的問題
    專案1 
    	django2.2 pymysql3.3 requests1.1
    專案2 
    	django1.1
    專案3
    	flask
諸多專案在你的機器上如何無障礙的開啟並執行
在實際開發過程中,我們會給不同的專案配備不同的環境,專案用到什麼就裝什麼,用不到的一概不裝,不同的專案直譯器環境都不一樣

# 建立虛擬環境 
	相當於在下載一個全新的直譯器
# 識別虛擬環境
	檔案目錄中有一個venv資料夾
# 如何切換環境
	選擇不用的直譯器即可 全文不要再次勾選new enviroment...

django版本區別

# django中1.x與2.x,3.x之間路由的區別
django1.X路由層使用的是url方法
django2.X和3.X版本中路由層使用的是path方法

1.X第一個引數正則表示式
url()
2.X和3.X第一個引數不支援正則表示式,寫什麼就匹配什麼,100%精準匹配
path()

# 如果想要使用正則,那麼2.X與3.X也有相應的方法
from django.urls import path,re_path

re_path 	# 等價於 1.X裡面的url方法
re_path(r'^index/',index),

# url 2.x和3.x不推薦使用 但是可以用
from django.conf.urls import url
url(r'^login/',login)

path支援五種轉換器

# 將第二個路由裡面的內容先轉成整型然後以關鍵字的形式傳遞給後面的檢視函式
path('index/<int:id>/',views.index)

def index(request,id):  # id當作關鍵字進來
    print(id,type(id))
    return HttpResponse('index')

# 五種轉換器
str,匹配除了路徑分隔符(/)之外的非空字串,這是預設的形式
int,匹配正整數,包含0。
slug,匹配字母、數字以及橫槓、下劃線組成的字串。
uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
path,匹配任何非空字串,包含了路徑分隔符(/)(不能用?)

自定義轉換器(瞭解)

class MonthConverter:
     # 屬性名必須為regex
    regex='\d{2}'  # 匹配兩個數字

    def to_python(self, value):
        return int(value)  # int型別

    def to_url(self, value):
        return value # 匹配的regex是兩個數字,返回的結果也必須是兩個數字
	
# 使用轉換器	
from django.urls import path,register_converter
from app01.path_converts import MonthConverter

# 先註冊轉換器
register_converter(MonthConverter,'mon')

from app01 import views


urlpatterns = [
    path('articles/<int:year>/<mon:month>/<slug:other>/', 	views.article_detail, name='aaa'),

]

檢視函式的返回值

# 檢視函式必須返回一個HttpResponse物件
HttpResponse
  	class HttpResponse(...):
      pass
	返回字串型別
render
	def render(...):
      return HttpResponse(...)
	返回html頁面 並且在返回給瀏覽器之前還可以給html檔案傳值
redirect
	def redirect(...):
	重定向

JsonResponse物件

# json格式的作用
前後端資料互動需要使用到json作為序列化,實現跨語言資料傳輸

# 前後端序列化
前端js序列化								後端序列化
JSON.stringify()						json.dumps()
JSON.parse()							json.loads()

json序列化

# 匯入模組
import json

def ab_json(request):
    # 將後端字典序列化傳送到前端
    user_dict = {'username':'jason', 'password':'123', 'hobby':'study'}
   # 先轉成json格式字串
    json_str = json.dumps(user_dict,ensure_ascii=False)
    # 將該欄位返回
    return HttpResponse(json_str)

'ensure_ascii 內部預設True自動轉碼,改為False不轉碼,只生成json格式,雙引號'

JsonResponse序列化

# 匯入JsonResponse模組
from django.http import JsonResponse

def ab_json(request):
    # 將後端字典序列化傳送到前端
    user_dict = {'username':'jason','password':'123', 'hobby':'study'}
# JsonResponse自動編碼並返回給前端頁面
return JsonResponse(user_dict,json_dumps_params={'ensure_ascii':False})

# 內部的原始碼
class JsonResponse(HttpResponse):
	def __init__(self, data,json_dumps_params=None, **kwargs):
		data = json.dumps(data, **json_dumps_params)

JsonResponse序列化(列表注意事項)

# 匯入JsonResponse模組
from django.http import JsonResponse

def ab_json(request):
    l = [111,222,333,444,555]
    # 預設只能序列化字典 序列化其他需要加safe引數 safe=False
    return JsonResponse(l,safe=False)  

form表單上傳檔案

# form表單上傳檔案型別的資料
前端:
    1.method必須指定成post
    2.enctype必須修改為multipart/form-data
    預設是application/x-www-form-urlencoded
後端:
    3.後端需要使用request.FILES獲取
'django會根據資料型別的不同自動幫你封裝到不同的方法中'

#具體程式碼: 
def ab_file(request):
    # 判斷前端請求
    if request.method == 'POST':
        print(request.FILES)  # 獲取檔案資料
        file_obj = request.FILES.get('file')   
        # (拿到最後一個元素)  檔案物件  
        print(file_obj.name)  # 拿到檔名字
        with open(file_obj.name, 'wb') as f:
            for line in file_obj:  
                f.write(line)
    # get請求返回
    return render(request, 'from.html')

# form
<form action="" method="post" enctype="multipart/form-data">
    <p>username: <input type="text" name="username"></p>
    <p>file: <input type="file" name="file"></p>
    <input type="submit">
</form>

request物件方法

# request.method 獲取請求方式POST/GET
一個字串,表示請求使用的HTTP 方法 必須使用大寫

# request.POST 獲取POST請求提交普通的鍵值對資料
一個類似於字典的物件,如果請求中包含表單資料,則將這些資料封裝

# request.GET 獲取GET請求
獲取GET請求	一個類似於字典的物件,包含 HTTP GET 的所有引數

# request.FILES 獲取檔案
一個類似於字典的物件,包含所有的上傳檔案資訊

# request.body 接收最原始的二進位制資料
request.POST、request.GET、request.FILES這些獲取資料的方法其實都從body中獲取資料並解析存放的

# request.path ,request.path_info 
獲取路徑 拿到路由

# request.get_full_path() 
能過獲取完整的url及問號後面的引數 

# 程式碼:
print(request.path)  # /app01/ab_file/
print(request.path_info)  # /app01/ab_file/
print(request.get_full_path())  # /app01/ab_file/?username=jason

FBV與CBV

# FBV:基於函式的檢視
'我們前面寫的檢視函式都是FBV'
  url(r'^index/',函式名)
    
# CBV:基於類的檢視
from django import views # 匯入CBV模組

class MyLoginView(views.View): # 繼承模組
    
    def get(self, request): # get請求走get函式
        return HttpResponse("from CBV get view")
    
    def post(self, request): # post請求走該post函式
        return HttpResponse("from CBV post view")
    
url(r'^ab_cbv/', views.MyLoginView.as_view())
    
"""
如果請求方式是GET 則會自動執行類裡面的get方法
如果請求方式是POST 則會自動執行類裡面的post方法
""" 
# CBV特點
能夠直接根據請求方式的不同直接匹配到對應的方法執行

CBV原始碼剖析

# CBV於FBV在路由匹配上本質是一樣的 都是路由 對應 函式記憶體地址
urlpatterns = {
	 url(r'^login/', views.MyLogin.as_view()) # CBV
	 url(r'^login/', views.view)  # FBV
}
# 切入點:路由匹配
  類名點屬性as_view並且還加了括號
as_view可能是普通的靜態方法  就是個普通函式沒有形參 
as_view可能是繫結給類的方法  類來呼叫自動將類傳入當做第一個引數傳入

步驟一

'函式名加括號執行優先順序最高'
urlpatterns = [
    # MyLogin類 點 方法
    url(r'^login/', views.MyLogin.as_view())  
]
# 原始碼顯示    
@classonlymethod  # 繫結給類的方法
	def as_view(cls, **initkwargs):  
    	pass
as_view: 繫結給類的方法,類來呼叫把類傳進去

步驟二

'專案已啟動就會執行as_view方法 檢視原始碼返回了一個閉包函式名view'
  def as_view(cls):
    def view(cls):
      pass
    return view
    
# 程式碼在啟動django的時候  就會立刻執行as_view方法 			
url(r'^login/', views.MyLogin.as_view())  # as_view 返回值 view

# django程式碼執行 以上程式碼就等價於以下程式碼段
url(r'^login/', views.view)  django專案啟動就等價於這個方法

'當用戶在瀏覽器輸入login的時候就自動執行 view方法'

步驟三

# 閉包函式(內部函式引用外部函式名稱空間中的名字) 
def view(request, *args, **kwargs):
    self = cls(**initkwargs)  # cls是我們自己寫的類的物件
    # self = MyLogin(**initkwargs)  產生一個我們自己寫的類物件
    
    # hasattr 對映 判斷物件是否包含對應屬性 (物件有該屬性返回True 否則返回False)
    if hasattr(self, 'get') and not hasattr(self, 'head'):
        # 給物件賦值屬性
        self.head = self.get
        self.request = request
        self.args = args
        self.kwargs = kwargs
        # 物件點dispatch 
        return self.dispatch(request, *args, **kwargs)
    
    # 面向物件屬性方法查詢順序
    1.先從物件自己名稱空間找
    2.在去產生類物件的類裡面找
    3.在去父類裡面找

    MyLogin >>名稱空間中查詢 >>產生類物件的類裡面找 >>父類查詢

    class MyLogin(View):  # 父類查詢

步驟四

def dispatch(self, request, *args, **kwargs):
	# 判斷 request.method將當前請求方式轉成小寫 在不在 self內 self==MyLogin 
        "http_method_names 內有八個請求方式 "
    ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
    if request.method.lower() in self.http_method_names:
    """
    # getattr 反射: 通過字串來操作物件的屬性或者方法
    # handler = getattr(self,'get'),你寫的類的get方法的記憶體地址
    # handler = getattr(自己寫的類產生的物件,'get',當找不到get屬性或者方法的時候就會用第三個引數)
    """    
    	handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
    else:
        handler = self.http_method_not_allowed
    return handler(request, *args, **kwargs) # 執行get(request)

模板語法傳值

# 模板語法兩種書寫方式
{{}}:變數相關

{%%}:邏輯相關
1.fro迴圈
2.反向解析配置load
'模板檔案中取值一律使用點語法'

# 傳值的兩種方式
傳值方式1:指名道姓的傳
return render(request, 'ab_temp.html', {'name':name})
'適用於資料量較少的情況       節省資源'

傳值方式2:打包傳值  
locals() 將當前名稱空間中所有的名字全部傳遞給html頁面
  return render(request, 'ab_temp.html', locals())
'適用於資料量較多的情況(偷懶)     浪費資源'

# 傳值的範圍 (基本資料型別都可以)
 1.函式名
  	模板語法會自動加括號執行並將函式的返回值展示到頁面上
    不支援傳參(模板語法會自動忽略有參函式)
 2.檔名
  	直接顯示檔案IO物件
 3.類名
  	自動加括號例項化成物件
 4.物件名
  	直接顯示物件的地址 並且具備呼叫屬性和方法的能力
    
# django模板語法針對容器型別的取值 只有一種方式>>>:句點符
	既可以點key也可以點索引  django內部自動識別
.key
.index
.key.index.index.key