Django基礎篇-3(前端tag、cvb模式)

這一篇接觸的內容是先後端分離的。關於先後端分離與不分離的區別,我本身的瞭解是先後端分離的狀況會使他們的耦合度更低,後端實現接口的部分,前端根據接口返回實現展現。而先後端不分離可能會用到一些 Django 的模版語言去識別和渲染。css

1、前端 tag 和自定義 tag

新建一個 html 文件用於展現本次頁面,在 views 中定義要展現的數據。html

 1 def test(request):
 2     import datetime
 3     cur_time = datetime.datetime.now()
 4     age = 18
 5     name = 'marry'
 6     article_content = "朝鮮一哥金三胖,已經登上太陽,爲了不太陽太熱,選擇晚上奔上太陽"
 7     say = "今天吃飯的時候,碰到一個傻x,那個傢伙實在是太213了,公然插隊,吃完飯在馬路上隨地大小便,夠sb的。"
 8     navs = ["個人日記", "個人相冊", '個人心情', '個人心情1', '個人心情2', '個人心情3']
 9     comment = "<h1 style='font-size:100px'>你好呀</h1>"
10     h1_str = '<p>哈哈哈</p>'
11     js_str="<script>alert('哈哈哈哈')</script>"
12     return render(request,'test.html',locals())#locals把當前全部局部變量返回

1. add

傳過來的內容能夠直接加上指定的內容,如對傳過來的 age 加1:前端

{{ age|add:'1' }}

當 age 是字符串類型時,加上指定的字符串即表明兩個字符串的拼接。python

2. 切片(slice)

若是對傳過來的內容截取想要的範圍,可使用 slice 這個方法,具體使用:{{ comment|slice:'0:20' }}。填的參數即角標,也是顧頭不顧尾。數據庫

3. truncatechars(截取前多少個字符顯示)

這個用在文章的概覽中,如一篇文章,不可能把全部內容都放在文章的列表中展現,此時可使用這個方法截取指定個數的字符: {{ comment|truncatechars:'40' }} django

若是截取的內容少於原來的內容,則截取的結果會用‘...’代替。json

4. list 拼接(join)

如上定義的 navs 是一個 list,若是想把其內容拿出來展現,可使用 join 方法,舉例: {{ navs|join:'===' }} 後端

5. 長度(length)

使用方法:{{ navs|length }}安全

可用於字符串也可用於 list。前後端分離

6. 取指定元素

{{ navs.0 }} 爲取第一個元素,可是不能使用 ‘-1’,在上篇寫分頁的時候遇到了這個問題,如何自動拿到最後一頁。思路:可使用 length 方法

7. 對英文字符的大小寫處理

所有大寫:{{ name|upper }}

所有小寫:{{ name|lower }}

另外,多個方法能夠鏈接使用,如:{{ name|upper|add:'小仙女' }}

8. 默認值

對某個要處理的字段增長默認值,拿不到的話顯示默認值:{{ author|default:'焦麗妃' }}

9. 對時間的處理

指定時間的格式:{{ cur_time|date:'Y-m-d h-i-s' }}

須要注意的是,這裏的分是用 i 表示的,不一樣於以往接觸到的用 m 表示。

10. js 和 css 注入

這個知識點也牽扯到安全性方面的知識,當前端接收到的數據是帶有 html 標籤時該如何處理。

一般不作任何操做的話,前端會把標籤看成普通字符串來處理,若是咱們想讓它識別爲標籤,能夠在後面加上‘safe’,表示是安全的。

{{ js_str|safe }}

11. 自定義標籤

當現有的功能沒法知足咱們的需求,好比說對敏感詞的替換。

添加自定義標籤時,在建立的項目下添加一個 python package,名爲「templatetags」

 1 from django import template
 2 
 3 register = template.Library()
 4 
 5 # 自定義filter最多兩個參數
 6 @register.filter
 7 def mingan(value,aim='金正恩'):
 8     if '金三胖' in value:
 9         value = value.replace('金三胖',aim)
10     return value

以上實現的是,若是包含上面定義的敏感詞,能夠替換爲使用者自定義的替換詞,替換詞爲空則使用默認值。

在 html 中的應用: {{ comment|mingan:'***' }} 

也能夠在 @register.filter(name='你想要的名字') 後面添加 name,這樣以後在用的時候就把 mingan 替換爲你定義的名字。

自定義標籤僅支持輸入兩個參數,當參數過多時,可使用 simple_tag,用法以下(接上面的內容寫在同一個文件中):

1 @register.simple_tag
2 def mingan3(value,*args):
3     for s in args:
4         if s in value:
5             value = value.replace(s,'**')
6     return value

這種方法能夠接收多個參數,使用起來更方便靈活。

 2、fvb 和 cvb

所謂 fvb,就是基於函數的視圖;cvb 則是基於類的視圖。

配置一個新的 URL,如 stu,目的是實現學生信息的增刪改查,若是每一個功能都寫一個URL的話,未免過於雜亂,能夠用同一個URL,經過不一樣的請求方式實現不一樣的功能。

  • GET→獲取學生信息
  • POST→修改學生信息
  • PUT→新增學生信息
  • DELETE→刪除學生信息

例如定義一個名爲 StudentView 的類,裏面包含了以上四種請求方式的實現。在URL的配置時,類視圖不一樣於函數視圖。

path('stu',views2.StudentView.as_view())

補充: as_view() 方法裏面實現了根據請求方式去找類裏面對應的方法名,若是是 get 請求,它就去找 get 這個函數,找不到就是不支持 get 請求。 

1. 使用 get 請求獲取用戶信息。

class StudentView(View):    #urls中的配置不同
    search_field = ['name','phone','addr','work_addr'] #存放支持搜索的字段
    filter_field = ['name','phone','id'] 
    
        def get(self, request):  # request 必需要傳
        limit = request.GET.get('limit', 10)
        page = request.GET.get('page', 1)
        search = request.GET.get('search')
        # 過濾
        filter_dict = {}  # 用來過濾的字典
        for field in self.filter_field:  # 循環獲取到有哪些過濾的字段
            value = request.GET.get(field)
            if value:
                filter_dict[field] = value
        # 模糊查詢
        q_result = Q()
        if search:
            for field in self.search_field:
                d = {'%s__contains' % field: search}
                q_result = Q(**d) | q_result
        all_students = Student.objects.filter(**filter_dict).filter(q_result).values()

        page_obj = Paginator(all_students, limit)
        stus = list(page_obj.get_page(page))
        data = {"error_code": 0, "msg": "操做成功", "count": page_obj.count, "stus": stus}
        return JsonResponse(data, json_dumps_params={'ensure_ascii': False}, encoder=NbJSONEncoder)

以上,request.GET 中包含了URL中填寫的信息,是一個QuerySet,能夠以字典的方式取值,當咱們在URL中傳參時,須要用 request.GET.get('***') 來獲取參數的具體內容。

模糊查詢和過濾的功能,代碼值得好好看。

2. 使用 post 請求新增數據。

    def post(self,request):
        stu_form = StudentForm(request.POST)
        if stu_form.is_valid():
            Student.objects.create(**stu_form.cleaned_data)
            data = {"error_code":0,"msg":"添加成功"}
        else:
            data = {"error_code":-1,"msg":stu_form.errors.get_json_data()}

        return JsonResponse(data,json_dumps_params={'ensure_ascii':False},encoder=NbJSONEncoder)

須要補充說明的是,原來使用 HttpResponse 返回數據,須要將數據轉成 json 格式的(json_dumps),其實也能夠直接用 JsonResponse 返回 json 數據,這個方法接收字典,返回 json。須要注意的是以後的參數定義也要用 json 格式的,如:json_dumps_params={'ensure_ascii':False}

3. 使用 put 請求修改數據

修改數據存在一個問題,簡單的實現時,一是不能實現局部修改,二是數據校驗的部分如何拿到傳過來的數據。已知能夠用 request.GET 拿到寫在URL中的參數,也能夠經過 request.POST 拿到 post 請求的數據,可是沒有一個 request.PUT 方法可供使用。

補充:request.META 能夠拿到全部的請求數據

put_data,files = request.parse_file_upload(request.META,request)

使用以上方法能夠解決獲取數據的問題。

如下爲解決部分修改和數據校驗

    put_data,files = request.parse_file_upload(request.META,request)
    stu_form = StudentForm(put_data) #它校驗的是所有的字段
    if stu_form.is_valid(): #經過校驗
        Student.objects.filter(id=id).update(**stu_form.cleaned_data)
        data = {"error_code": 0, "msg": "修改爲功"}
    else:
        error_keys = set(stu_form.errors.get_json_data().keys())
        put_keys = set(put_data.keys())
        if error_keys & put_keys: #有交集說明有未校驗經過的
            data = {"error_code": -1, "msg": stu_form.errors.get_json_data()}
        else: #沒有交集說明有未填字段,須要部分更新
            for k in put_keys: #put_data給的字典value默認是list,須要處理一下
                clean_data[k] = put_data.get(k)
            Student.objects.filter(id=id).update(**clean_data)
            data = {"error_code": 0, "msg": "修改爲功"}
    return JsonResponse(data, json_dumps_params={'ensure_ascii': False})

put_data 爲傳過來的數據

stu_form 校驗的是所有的字段,若是經過,說明修改的是所有字段,若是未經過,進一步判斷。

校驗未經過分爲兩種狀況:

  1. 所有字段有不符合要求的狀況

  2. 部分修改

先定義報錯的信息,由於若是某個字段未經過校驗,會把這個字段看成key,錯誤信息看成 value 存放在stu_form.errors.get_json_data()。因此,error_keys 存放報錯的 key,put_keys 存在傳過來的 key。

對第一種狀況,就是 error_keys 和 put_keys 有交集,意思是傳了值但沒經過校驗;對第二種狀況,兩個 keys 沒有交集,說明傳過來的都經過校驗,沒經過校驗是由於沒有傳,對這部分字段不作修改,只修改 put_keys 傳過來的,進而達到部分修改的目的。

 4. DELETE 實現刪除數據功能

    def delete(self,request):
        id = request.GET.get('id',0)
        Student.objects.filter(id=id).delete()
        data = {"error_code":0,"msg":"刪除成功"}
        return JsonResponse(data,json_dumps_params={'ensure_ascii':False},encoder=NbJSONEncoder)

除 get 請求,其餘請求方式在測試時須要用 postman 來驗證。

3、Form(用來校驗請求數據)

 1 class StudentForm(forms.Form): #爲student作數據校驗
 2     name = forms.CharField(min_length=2,max_length=10,required=True) #required=True表示必填,默認必填
 3     phone = forms.CharField(min_length=11,max_length=11)
 4     money = forms.FloatField(required=False)
 5 #     自定義函數校驗是否字段重複
 6     def clean_phone(self):
 7         '''鉤子'''
 8         phone = self.cleaned_data['phone']
 9         if models.Student.objects.filter(phone=phone):
10             return self.errors.add('手機號錯誤','手機號已經存在')
11         return phone
12     # def clean(self):
13     #     '''多個字段校驗'''
14     #     pass

這是一種稍微麻煩點的數據校驗的方法,是把要校驗的數據本身定義了寫在函數中。

另一種是直接繼承 ModelForm,使用的校驗方法是在數據庫定義時的校驗方法,以下:

class StudentForm(ModelForm):
    class Meta:
        model = Student
        # fields ='__all__'
        fields = ['name','phone']
        exclude = ['money'] #排除哪一個字段

使用的方法爲: stu_form = StudentForm(request.POST) 

後面括號中傳的是要校驗的數據。上面也提到了,這個方法是校驗全部的字段,若是某個字段未經過校驗,會把這個字段看成key,錯誤信息看成 value 存放在stu_form.errors.get_json_data()。

o

O

相關文章
相關標籤/搜索