django初步瞭解3

JsonResponse模塊

經過此模塊,若不設置參數,則會把中文轉成二進制,因此就須要設置參數ensure_ascii了html

def index(request):
    user = {'username':'jason真帥 我好喜歡哦~','pwd':'123'}
    # json_str = json.dumps(user,ensure_ascii=False)
    # return HttpResponse(json_str)
    return JsonResponse(user,json_dumps_params={'ensure_ascii':False})
    # l = [1,2,3,4,5,5,6]
    # return JsonResponse(l,safe=False)
    # JsonResponse默認只支持序列化字典 若是你想序列化其餘類型(json可以支持的類型) 你須要將safe參數由默認的True改爲False

須要注意的是轉字典意外的其餘格式,需設置safe參數!!!前端

額外贈品?python

額外贈品?django

額外贈品?json

import json
from datetime import datetime

"""
TypeError: Object of type 'datetime' is not JSON serializable
"""
class MyJsonClass(json.JSONEncoder):
    def default(self, o):
        if isinstance(o,datetime):  # 若是o不是json默認可以序列化 你就在該方法內給他處理成json可以轉的類型
            return o.strftime('%Y-%m-%d')
        else:
            super().default(self,o)
d = {'ctime':datetime.today()}
print(json.dumps(d,cls=MyJsonClass))

這裏是用json模塊來轉json不支持的數據類型。。。將就着看吧閉包

form表單上傳文件

若是直接上傳,用post的方式不設置其餘參數,則只會上傳文件名字,解決方法就是,在前段form表單處設置屬性enctype=「formdata」。函數

作到這裏時你覺得成功了嗎?oop

不,當你打印request.POST時發現連文件名都沒了???源碼分析

其實當設置了以後,文件就會以另外一種方式上傳,打印request.FILES你就會看見它

def up(request):
    if request.method == 'POST':
        print(request.POST)
        print(request.FILES)
        # 獲取文件對象
        file_obj = request.FILES.get('myfile')
        print(file_obj.name)  # 獲取文件名
        with open(file_obj.name,'wb') as f:
            # for line in file_obj:  # file_obj你能夠直接當作文件句柄f
            for chunk in file_obj.chunks():  # file_obj你能夠直接當作文件句柄f(官方推薦下面這麼寫,其實沒差異)
                f.write(chunk)
    return render(request,'up.html')

FBV與CBV

FBV(Function Based View) 基於函數的視圖
CBV(Class Based View) 基於類的視圖

CBV路由:

url(r'^reg/',views.MyReg.as_view())

思考一下?

你在類中寫了兩個方法 一個叫get一個叫post
爲何前端get請求來就會觸發get方法
post請求來就會觸發post方法 如何實現的???

源碼分析開始了!

源碼分析開始了!

源碼分析開始了!

@classonlymethod
        def as_view(cls, **initkwargs):
            def view(request, *args, **kwargs):
                self = cls(**initkwargs)  # cls就是咱們本身的寫的MyReg類
                if hasattr(self, 'get') and not hasattr(self, 'head'):
                    self.head = self.get
                self.request = request
                self.args = args
                self.kwargs = kwargs
                # 上面的一通操做 就是給咱們本身寫的類的對象賦值
                return self.dispatch(request, *args, **kwargs)
                # 對象在查找屬性或方法的時候 順序是什麼?  先從本身找 再從產生對象的類中找  再去類的父類中找...
                """也就意味着你在看源碼的時候 你必定要牢記上面的話"""
            return view

先看看這段源碼,從as_view()按ctrl點進去。很明顯這是個閉包函數,最終返回一個view對象,因此接下來看view方法,if後面4行這是在賦值相似於初始化,由於self = cls(**initkwargs)建了一個新的對象,cls則是咱們在視圖中寫的類,賦值後執行dispatch方法,很明顯,接下來就是點進這個方法中看源碼...

"""CBV最精髓的部分"""
        def dispatch(self, request, *args, **kwargs):
            if request.method.lower() in self.http_method_names:  # 判斷當前請求方式在不在默認的八個請求方式中
                handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
                # handler = getattr(本身寫的類產生的對象,'小寫的請求方法(get\post)','獲取不到對應的方法就報錯')
                # handler就是咱們本身定義的跟請求方法相對應的方法的函數內存地址
            else:
                handler = self.http_method_not_allowed
            return handler(request, *args, **kwargs)  # 在調用獲取到的方法

這個方法就是關鍵所在了,先判斷方法是否符合規則,而後利用反射直接調用,簡單粗暴-。-

django settings源碼分析及實際應用

後續補更ing...

模板語法

模板傳值

傳函數名的時候 會自動加括號調用函數 將函數的返回值展現在html頁面上

​ 1.django模板語法不支持函數傳參

​ 2.django模板語法在獲取容器類型內部元素的值的時候 統一隻採用 句點符(.)

模板過濾器

過濾器 有點相似於小的方法

特色 會將|左邊的當作過濾器的第一個參數 |右邊的當前過濾器第二個參數

#add過濾器,結果是兩個參數相加
<p>{{ n|add:100 }}</p>
<p>{{ n|add:'abc' }}</p>
<p>{{ s|add:'sasahhdasda' }}</p>

#length過濾器,取長度
<p>{{ l|length }}</p>
<p>{{ d|length }}</p>

#filesizeformat過濾器取文件長度
<p>{{ file_size|filesizeformat }}</p>

#truncatechars截取必定數量的字符
<p>截取10個字符 三個點也算{{ w1|truncatechars:10 }}</p>
<p>截取10個字符 三個點也算{{ w|truncatechars:10 }}</p>

#truncatewords截取指定限制條件和數量的字符
<p>按空格截取單詞 三個點不算{{ w1|truncatewords:6 }}</p>
<p>按空格截取單詞 三個點不算{{ w|truncatewords:6 }}</p>
<p>按空格截取單詞 三個點不算{{ w2|truncatewords:6 }}</p>

#slice切片
<p>{{ l|slice:'0:5' }}</p>
<p>{{ l|slice:'0:5:2' }}</p>

#date日期輸出格式
<p>{{ ctime|date:'Y-m-d' }}</p>
<p>{{ ctime|date:'Y年/m月' }}</p>

#safe讓標籤變得能被解釋
<p>{{ sss|safe }}</p>
<p>{{ sss1|safe }}</p>
<p>{{ res }}</p>

#default無值則取默認值
<p>{{ xo|default:'' }}
有值就拿值 沒值就用後面默認的
</p>

標籤

if標籤

{% if xo %}
    <p>xo有值</p>
{% else %}
    <p>xo沒有值</p>
{% endif %}

{% if xo %}
    <p>xo有值</p>
{% elif xo1 %}
    <p>xo1有值</p>
{% else %}
    <p>去他大爺的</p>
{% endif %}

for標籤

{% for foo in l %}
    {% if forloop.first %}
        <p>這是個人第一次</p>
    {% elif forloop.last %}
        <p>這是最後一次了啊</p>
    {% else %}
        <p>嗨起來 大寶貝~</p>
    {% endif %}
{% endfor %}


{% for foo in xo %}
    <p>{{ forloop.counter }}:{{ foo }}</p>
    {% empty %}判斷是否爲空
    <p>你給個人對象是個空的無法進行for循環</p>
{% endfor %}

with標籤

<p>{{ yyy.user_list.2.username.1 }}</p>

{% with  yyy.user_list.2.username.1 as dsb %}
    <p>{{ dsb }}</p>
    <p>{{ yyy.user_list.2.username.1 }}</p>
{% endwith %}

自定義過濾器和標籤

步驟:

​ 1.在應用名下面建立一個叫templatetags的文件夾

​ 2.在該文件夾中任意建一個py文件

​ 3.在py文件中先固定寫兩行代碼

​ from django.tempalte import Library

​ register = Libyary()

自定義

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


            @register.simple_tag(name='mysm')
            def login(a,b,c,d):
                return '%s/%s/%s/%s'%(a,b,c,d)
        
            區別 標籤不能再if中使用
            {% if 0|myplus:123 %}  能夠用
                <p>有值</p>
            {% endif %}


            {% if mysm 1 2 3 4 %}  不能用
                <p>有值</p>
            {% endif %}

模板繼承

事先須要再模板中 經過block劃定區域
        
                {% block 區域名字 %}

                {% endblock %}
        子板中如何使用
                {% extends '模板的名字'%}
                
                {% block 區域名字 %}
                    <h1>登陸頁面</h1>
                {% endblock %}
                        
        一個頁面上 block塊越多 頁面的擴展性越高
        一般狀況下 都應該有三片區域
                {% block css %}

                {% endblock %}
                
                {% block content %}

                {% endblock %}
                
                {% block js %}

                {% endblock %}
        
        子板中還能夠經過
            {{ block.super }}  來繼續使用母版的內容

模板導入

當你寫了一個特別好看的form表單 你想再多個頁面上都使用這個form表單
你就能夠將你寫的form表單看成模塊的形式導入 導入過來以後 就能夠直接展現
        
{% include 'good_page.html' %}
相關文章
相關標籤/搜索