JsonResponse類的使用、form表單上傳文件補充、CBV和FBV、HTML的模板語法之傳值與過濾器

昨日內容回顧

  • Django請求生命周期
# 1.瀏覽器發起請求 到達Django的socket服務端(web服務網關接口)
	01 wsgiref
	02 uwsgi + nginx
	03 WSGI協議
    
# 2.Django框架
	01 中間層
	02 路由層
		django1.x:url('正則表達式','視圖函數的內存地址')
		django2.x:
			path() => 精準匹配
			re_path  => url => 支持正則表達式
	03 視圖層:views.py
	04 模板層:頁面
	05 模型層:數據
	06 DB  
  • 路由層
1. url()
2. 無名分組和有名分組:
	無名分組: 就是把正則表達式用括號括起來,當成位置參數傳遞給視圖函數
	有名分組: 就是把正則表達式用括號括起來,當成關鍵字參數傳遞給視圖函數
		url('test/(?P<path>\d+)')
        
3. 反向解析
	通過給路由起一個別名,通過解析別名得到該行鎖對應的路由地址
    
 4. 無名和有名反向解析
  • 路由分發
# 當django項目特別大的時候,就會出現許多的路由地址,總路由的壓力就會很大
	django的每一個應用都支持有自己的路由文件,模板文件,static文件...

	總路由就只負責分發路由,不再做路由地址與視圖函數的對應關係
    
eg:
	from app01 import urls as app01_urls
	from app02 import urls as app02_urls
	from app03 import urls as app03_urls
    
	url('app01/', include(app01_urls))
	url('app02/', include(app02_urls))
    
	//127.0.0.1:8000/app01/v1/v2/index
            
            
	url('app01/', include('app01.urls', namespace='app01'))
	url('app01/', include('app02.urls',namespace='app01'))
	reverse('app01:index')
	reverse('app02:index')   
  • 虛擬環境
# 1. 創建了一個新的python解釋器

# 2. 在不同的項目中使用不同的python環境

# 3. 不要一直創建虛擬環境

今日內容概要

  • JsonResponse類的使用
  • form表單上傳文件
  • CBV和FBV
  • CBV的源碼分析
  • 模板層
    • 模板語法之傳值
    • 模板語法之過濾器

內容詳細

1. JsonResponse 類的使用

# 1. 混合開發項目:前端頁面和後端代碼寫到一塊

# 2. 前後端分離項目:前端是一個項目,後端是一個項目,後端只需要寫接口

# json格式的數據:進行跨語言數據傳輸


# Python中兩個數據傳輸模塊:
	01 import json
	'''支持的數據類型:str,list, tuple, dict, set'''
	# 序列化出來的數據是可以看得懂的,就是一個字符串
	四種方法:
		dumps
		loads

		dump
		load
    
	02 import pickle
	'''支持的數據類型:python中的所有數據類型'''
	# 序列化出來的結果看不懂,因為結果是一個二進制
	# pickle序列化出的來的數據只能在python中使用
	四種方法:
		dumps
		loads

		dump
		load
        

# js中如何序列化?
	JSON.stringify()  # 序列化
	JSON.parse()      # 反序列化
    

#  JsonResponse 類使用演示
	1.傳輸字典 但字典內容包含中文
在 views.py文件中寫入:
"""
from django.shortcuts import render, HttpResponse, redirect
# Create your views here.

from django.http import JsonResponse

def index(request):
    user_dict = {'username': 'justin歌手', 'password': 123}
    return JsonResponse(user_dict, json_dumps_params={'ensure_ascii': False})  # 如果不包含中文 去掉 json_dumps_params參數即可
"""

在路由URLS.PY文件中寫入:
"""
from app01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^index/', views.index),
]
"""
	
	2.傳輸列表
在 views.py文件中寫入:
"""
from django.http import JsonResponse

def index(request):
    l = [1, 2, 3, 4, 5]
    return JsonResponse(l, safe=False)
"""

在URLS.PY文件中保持不變

image

image

2. form表單上傳文件

# 上傳文件注意事項:
	1. 必須是post請求
	2. form表單的enctype參數必須為:
		enctype='multipart/form-data'
	後端:
		在request.FILES中接收文件數據,其他數據一律按照請求方式接收
    
    
# 補充知識:
"""
數據格式有哪些:
	1. urlencoded
	2. form-data
	3. json格式
    
form表單可以傳遞的數據格式:
	1. urlencoded
	2. form-data
 	# 不能提交json格式的數據

提交json格式的數據:
	1. ajax
	2. 第三方工具
		postman
		apizza
"""


# 在urls.py文件中添加路由:
	url(r'^upload/', views.upload),

# 在views.py文件中添加功能:
"""
def upload(request):
    # POST是拿不到文件數據的
    print(request.POST)
    print(request.FILES)

    if request.method == 'POST':
        print(request.FILES)
        file_obj = request.FILES.get('myfile')
        print(file_obj.name)  # 文件名

        import uuid
        # 避免文件名重複導致數據被覆蓋
        aa = str(uuid.uuid4()) + '.png'
        with open(aa, 'wb') as f:
            for line in file_obj:
                f.write(line)

    return render(request, 'upload.html')
"""

# 新建HTML文件 upload.hyml:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="//cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <link href="//cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="//cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
    <form action="" method="post" enctype="multipart/form-data">
        <p>username: <input type="text" name="username"></p>
        <p>file: <input type="file" name="myfile"></p>
        <p>
            <input type="submit" value="提交">
        </p>
    </form>
</body>
</html>

image

3. CBV 和 FBV

# FBV: function based view

# CBV
# 在views.py文件中添加:
"""
# 必須繼承一個類
from django.views import View

class IndexView(View):
    def get(self, request):
        print('get')
        return HttpResponse('get')
    def post(self, request):
        print('post')
        return HttpResponse('post')
"""

# 在urls.py文件中添加路由:
	url(r'^indexCbv/', views.IndexView.as_view()),

image

4. CBV的源碼

如何通過請求方式確定的方法?

#############入口################################
def view(request, *args, **kwargs):
    self = cls(**initkwargs)  # self = IndexView(**initkwargs)
    # self => IndexView
    return self.dispatch(request, *args, **kwargs)

##############核心方法################################
def dispatch(self, request, *args, **kwargs):
    # GET POST  => get post
    if request.method.lower() in self.http_method_names:
        # 反射:get set has del
        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, *args, **kwargs)

5. 模板語法之傳值

# 傳值
	跟變量相關的都使用雙括號 {{}}
	跟邏輯相關的都使用 {%  %}
	'''模板文件中取值一律使用點語法 . '''
	在模板文件裏面的函數,不用加括號,會自動加括號調用, 不能傳遞參數
    
# 在views.py文件中添加:
"""
def test(request):
    # user_dict = {'a':1}
    a = 11
    b = 1.11
    c = 'hello world'
    d = [1, 2, 3, ['a', 'b', {'hobby': ['football', 'baseball']}]]
    e = {'username': 'ly'}
    f = True
    g = (1, 2, 3)
    l = {1, 2, 3, 4}
    h = open('a.txt', 'w')

    def info():
        print('info')
        return 'info'
    return render(request, 'test.html', locals())
"""
# 在urls.py文件中添加路由:
	url(r'^test/', views.test),
    
# 新建test.html文件:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="//cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <link href="//cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="//cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>

{{ a }}
{{ b }}
{{ c }}
{{ d.3.2.hobby.0 }}
{{ e }}
{{ f }}
{{ g }}
{{ h }}
{{ l }}
{{ info }}
</body>
</html>

image

6. 模板語法之過濾器

# 相當於python裏面的內置方法

# 語法:
	{{變量|過濾器:參數}}
    
# 過濾器有很多個,大概有六七十,我們只需要掌握5個左右
	1. length
	2. defalut
	3. date
	4. filesizeformat
	5. safe

# 過濾器裏面最大傳兩個參數,至少一個參數


# 在views.py文件中:
"""
def test(request):
    c = 'hello world'
    f = False

    import datetime
    ctime = datetime.datetime.now()
    gg = 123456789
    hh = '<h1>hello<h1>'  # 後端加safe 會渲染成h1標籤
    return render(request, 'test.html', locals())
"""

# 在test.html文件中:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="//cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <link href="//cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="//cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
{{ c|length }}

{{ f|default:'這是默認值' }}
{#{{ f|default:'這是默認值' }}#}

{{ ctime|date:'Y-m-d H:i:s' }}

{{ gg|filesizeformat }}

{{ hh|safe }}

</body>
</html>

image