day54

視圖層

  • 小白必會三板斧css

    HttpResponsehtml

    render前端

    redirectpython

    視圖函數必須有一個返回值 而且返回值的數據類型必須是HttpResponse對象django

  • JsonResponsejson

    先後端分離後端

    ​ 先後端數據交互 該如何進行?瀏覽器

    ​ 一般狀況下先後端的數據交互採用的都是json的字符串(字典)前端工程師

    後端只須要寫好相應的url接口 前端訪問你這個接口閉包

    你只須要返回一個大字典便可+開發文檔

    用來告訴前端工程師 你這個接口可以返回那些數據

    先後端序列化都用哪些方法

    python後端 js

    json.dumps JSON.stringify

    json.loads JSON.parse

def index(request):
user_dic = {'name':'jason好帥哦 我好喜歡~','password':'123'}
# 如何讓json不自動幫你對中文進行轉碼,把ensure_ascii設置爲false,默認的是true
# json_str = json.dumps(user_dic,ensure_ascii=False)
# return HttpResponse(json_str)
# return JsonResponse(user_dic,json_dumps_params={'ensure_ascii':False})
l = [1,2,3,4,5,6,7,]    #若是容器類型數據爲空的時候 不執行任何語句
# JsonResponse默認是序列化字典用的 若是你想序列化其餘數據類型(json模塊可以序列化的) 你須要加一個safe參數
return JsonResponse(l,safe=False)
  • FBV與CBV

    FBV:是基於函數視圖

    CBV:是基於類的視圖

from django.views import View


class MyLogin(View):
	def get(self,request):
        print('我是MyLogin裏面的get方法')
        return render(request,'login.html')

def post(self,request):
        print('我是MyLogin裏面的post方法')
        return HttpResponse('post')

# 路由的書寫 與CBV有點不一樣
        # FBV寫法     路由 >>> 視圖函數內存地址
        url(r'^index/',views.index),
        # CBV寫法
        url(r'^login/',views.MyLogin.as_view())
  • CBV的源碼

    爲何CBV可以根據請求的不一樣 自動執行不一樣的方法?

    訪問屬性和方法

    方法就是函數(函數名加括號執行優先級最高)url(r'^login/',views.MyLogin.as_view())

    項目一啓動 會自動執行as_view方法

    CBV在路由上匹配 其實本質就是FBV 路由 >>>>視圖函數內存地址

    # CBV寫法
        url(r'^login/',views.MyLogin.as_view()),
        # url(r'^login/',views.view)
        # 訪問屬性和方法
        # 方法就是函數(函數名加括號執行優先級最高)
        # 項目一啓動 會自動執行as_view方法
        # views.test和上面登陸的views.view本質上寫法是同樣的,CBV在路由匹配上 其實本質仍是FBV    路由 >>> 視圖函數內存地址
        url(r'^test/',views.test),
        
            
        url(r'^index/',views.index),#index在匹配上路由的時候觸發
        url(r'^login/',views.MyLogin.as_view()),#在瀏覽器上出入login就會觸發
    
    
    # 若是在urls中設置url(r'',home),會截獲全部的url,若是放在文件的下面不截獲
    #網站首頁可使用url(r'^$',home)
    #訪問網站404頁面的設計 url(r'',error)
@classonlymethod
			def as_view(cls, **initkwargs):
				def view(request, *args, **kwargs):  #閉包函數
				self = cls(**initkwargs)  # cls是咱們本身寫的類 MyLogin self是咱們自定義的類的對象
                #在看源碼的時候  你必定要把握住一個順序  對象在查找屬性和方法的時候
                #先從對象自身找  再去產生對象的類中找  再去類的父類中找
                return self.dispatch(request, *args, **kwargs)
            return view     #view返回的是內部函數的函數名




def dispatch(self, request, *args, **kwargs):
				# Try to dispatch to the right method; if a method doesn't exist,
				# defer to the error handler. Also defer to the error handler if the
				# request method isn't on the approved list.
				#判斷當前請求方式在不在默認的八個方法內
				======1.先以GET方法爲例======
				if request.method.lower() in self.http_method_names:
					#利用反射去咱們自定義類的對象中查找get屬性或者是方法  getattr(obj,'get')
					#handler = 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方法
  • 給CBV加裝飾器
給CBV加裝飾器  推薦使用內置模塊
from django.utils.decorators import method_decorator
======2.能夠指定給誰裝======
#@method_decorator(outter,name='post')
#@method_decorator(outter,name='dispatch')
class MyLogin(View):
			@method_decorator(outter)
			def dispatch(self, request, *args, **kwargs):  # 若是你想在視圖函數執行以前  作一些操做  你能夠在你的CBV中定義dispatch方法來攔截
				return super().dispatch(request,*args,**kwargs)
			# @outter  # 1.直接寫
			# @method_decorator(outter)  # 1.推薦寫法
			def get(self,request):
				print('我是MyLogin裏面的get方法')
				return render(request,'login.html')
			# @outter
			def post(self,request):
				print('我是MyLogin裏面的post方法')
				time.sleep(1)
				return HttpResponse('post')

模板層

  • 模板語法

    只有兩種書寫格式

    {{}} 變量相關

    {%%} 邏輯相關

  • 模板傳值

    到底能傳哪些數據類型

    python基本數據類型所有支持傳值

    <p>  傳函數名{{index}}
    給html頁面傳遞函數名的時候  模板語法會自動加括號調用函數   而且將函數的返回值當作展現依據   
    模板語法不支持函數傳參  也就意味着  你傳給html頁面的只能是不須要傳參調用的函數
    </p> 
    
    <p>傳類名:{{MyClass}}
    </p>
    <p>{{ obj.get_self }}</p>
    <p>{{ obj.get_cls }}</p>
    <p>{{ obj.get_func }}</p>
    <p>只要是可以加括號調用的  傳遞到html頁面上的都會自動的加貨號調用</p1>
    
    
    給html頁面傳值的兩種方式
    第一種   指名道姓   當須要傳遞的變量名特別多的狀況下  有點麻煩  
    return render(request,'test.html',{'n':n})
    第二種   locals()  會將當前所在的名稱空間中全部的名字 所有傳遞給html頁面
    return render(request,'test.html',locals())
  • 過濾器

    語法結構

    模板語法也給你提供了一些的內置的方法 幫你快速的提供處理數據的能力

    最可能是兩個參數

    前端的取消轉義

    |false

    後端

from django.utils.safestring import mark_safe
sss2 = "<h2>個人h2標籤</h2>"
res = mark_safe(sss2)

<p> 模板語法之過濾器   會自動將|左邊的數據當前過濾器的第一個參數 傳入  :右邊的當作第二個參數</p>
{<p>統計長度(若是沒法統計默認返回0):{{s|length}}</p>}
{<p>加法運算(內部異常捕獲  支持數字相加  字符串拼接  都不符合返回空):{{n|add:f}}</p>}
{<p>切片操做  顧頭不顧尾  也支持步長 :{{l|slice:'0:5:3'}}</p>}
{<p>判斷是否有值 (有值展現值的自己  沒有值展現默認的值):{{ is_value|default:'is_value變量名指向的值爲空' }}</p>}
{<p>自動轉成文件大小的格式:{{file_size |filtesizeformat}}</p>}
{<p>截取文件的內容(字符) 截取五個字符  後面的三個點也算:{{ s|truncatechars:8 }}</p>}
{<p>截取文本的內容(按照空格計算) 截取五個單詞 三個點不算:{{s1|truncatewords:5}}</p>}
{<p>默認狀況下  是不會自動幫你轉換成前端的html標籤的   防止惡意攻擊</p>}
{<p>展現帶有標籤的文本:{{sss|safe}}</p>}
{<p>展現帶有標籤的文本:{{sss1|safe}}</p>}
  • 標籤

    邏輯相關的

    if

    for循環

    for if聯合使用
    			{% for foo in l %}
    				{% if forloop.first %}
    					<p>這是個人第一次</p>
    				{% elif forloop.last %}
    					<p>這是最後一次了啊</p>
    				{% else %}
    					<p>{{ foo }}</p>
    				{% endif %}
    				{% empty %}
    					<p>當for循環的對象是空的時候會走</p>
    			{% endfor %}
    			
    <p>模板語法的取值  只有一種方式  統一採用點(.)的方式</p>
    <p>{{ comp_dic.hobby.2.2.age }}</p>
    當你的數據是經過比較複雜的點點點獲取到的後續又須要常用   你能夠給該數據起別名   別名只能在with內部使用
    {% with comp_dic.hoby.2.2.age as age %}
    <p>{{age}}</p>
    <p>{{ comp_dic.hoby.2.2.age}}</p>
    {% endwith%}
  • 自定義過濾器和標籤

    django支持用戶自定義

    必需要先有三步準備

    1.在應用名下新建一個名字必須是templatetags文件夾

    2.在該文件夾內 新建一個任意名稱的py文件

    3.在該文件中 必須先寫下面的兩句代碼

    from django.template import Library

    register = Library()

    以後就能夠利用register來自定義過濾器和標籤

  • 使用自定義的過濾器

    須要先在html頁面上 加載

    自定義過濾器 跟默認的過濾器同樣 最多隻能接受兩個參數

    @register.filter(name='baby')
    def index(a,b)
    return a+b

    自定義標籤

    自定義的標籤能夠接受任意多個參數

    @register.simple_tag(name='mytag')
    def mytag(a,b,c,d):
    return '%s?%s?%s?%s?'%(a,b,c,d)

    自定義inclusion_tag

    是一個函數 可以接受外界傳入的參數 而後傳遞給一個html頁面

    頁面上獲取的數據 渲染 完成以後

    將渲染好的頁面 放到調用inclusion_tag 的地方

    自定義inclusion_tag
    @register.inclusion_tag('mytag.html',name='xxx')
    			def index666(n):
    				l = []
    				for i in range(n):
    					l.append('第%s項'%i)
    				return locals()  # 將l直接傳遞給mytag.html頁面
    		
    			{#<p>自定義過濾器的使用</p>#}
    			{#{% load mytag %}#}
    			{#{{ 1|baby:1  }}#}
    			{#{{ 1|baby:100  }}#}
    			
    			自定義標籤的使用   能夠接受多個參數 參數之間必須空格隔開
    			{#{% load mytag %}#}
    			{#{% mytag 'a' 'b' 'c' 'd' %}#}
    			{#{% load mytag %}#}
    			自定義的過濾器能夠在邏輯語句使用   而自定義的標籤不能夠
    			{#{% if mytag '1' '2' '3' '4' %}#}
    			{#    <p>有值</p>#}
    			{#    {% else %}#}
    			{#    <p>無值</p>#}
    			{#{% endif %}#}
    			自定義inclusion_tag 的使用  當你須要使用一些頁面組件的時候  而且該頁面組件須要參數纔可以正常渲染  你能夠考慮使用inclusion_tag 
    			{% load mytag %}
    			{% xxx 5 %}
    			
    			
    			
    標籤    邏輯相關
    索引:'counter0':0
    計數:'counter':1
    可以判斷for循環的開始:'first':True
    可以判斷for循環的結束:'last':True
  • 模板繼承

    你須要事先在你想要使用的頁面上 劃定區域 以後在繼承的時候 你就可使用你劃定的區域

    也就意味着 若是你不劃定任何區域 那麼你就將沒法修改頁面上的內容

    {% block content %}
    {% endlock %}
    先在頁面上利用block劃定你之後可能想改的區域
    
    繼承以後 就能夠經過名字找到對應的區域進行修改
    {% extends 'home.html'%}
    {% block content %}
    修改模板中content區域內容
    {% endblock %}
    
    模板上的block區域越多  頁面的擴展性越高 
    建議你一個模板頁面至少有三塊區域
    
    css區域
    html代碼區域  能夠設置多個block
    
    js區域
    有了這三塊區域  就能實現每個頁面都有本身獨立的css和js代碼
    {% extends 'home.html' %}
    
    
    			{% block css %}
    				<style>
    					p {
    						color: green;
    					}
    				</style>
    			{% endblock %}
    
    			{% block content %}
    			<p>login頁面</p>
    			{% endblock %}
    
    
    
    			{% block js %}
    				<script>
    					alert('login')
    				</script>
    			{% endblock %}
    		你還能夠在子頁面上繼續沿着父頁面的內容
            {{ block.super }}
            
            
            模板的繼承
            先在你想要繼承的頁面上經過block劃定你將要改動的區域
            在子頁面上先繼承extends
            利用block自動提示  選擇你想要修改的內容的區域
  • 模板導入

    將html頁面當作模塊的直接導入使用

    {% include 'bform.html' %}

靜態文件目錄路徑

STATICFILES_DIRS = [os.path.join(BASE_DIR,'static')]
相關文章
相關標籤/搜索