1. 程式人生 > 實用技巧 >django介面開發-程式碼優化views_get

django介面開發-程式碼優化views_get

#利用cbv的繼承特性,進行views中程式碼優化

#把views中的程式碼拆出來,新建custom_view.py,把cbv-class從views中挪進去

#自定義view,custom_view.py中新建一個BaseView 用於定義條件變數
import datetime
from itertools import chain

from django.core.paginator import Paginator
from django.db.models import Model
from django.http import JsonResponse
from django.views import
View from example import models def model_to_dict(instance, fields=None, exclude=None): opts = instance._meta data = {} for f in chain(opts.concrete_fields, opts.private_fields, opts.many_to_many): if fields and f.name not in fields: continue if exclude and f.name in
exclude: continue value = f.value_from_object(instance) if isinstance(value, datetime.datetime): value = value.strftime('%Y-%m-%d %H:%M:%S') if isinstance(value, datetime.date): value = value.strftime('%Y-%m-%d') data[f.name] = value
return data #BaseView中定義條件變數 class BaseView(View): model_class = None #1-傳遞類變數 fields = [] #2-返回指定欄位 exclude_fields = [] #3-指定返回時過濾掉哪些欄位 filter_fields = [] #4-按照什麼欄位進行過濾 search_fields = [] #5-按照什麼欄位進行模糊匹配,前端傳key=search的欄位 #1-驗證model_clsss不傳的時候 @property def model(self): #issubclass:引數1是不是引數2的子類,校驗model_class if self.model_class and issubclass(self.model_class,Model): return self.model_class raise Exception("未定義model_class") def get_filter_dict(self): filter_dict = {} for filed in self.filter_fields: #通過request取到name值 value = self.request.GET.get(filed) if value: filter_dict[filed] = value return filter_dict def get_search_dict(self): #只能模糊查詢一個欄位 search_dict = {} value = self.request.GET.get('search') if value: search_dict = {"%s__contains" %self.search_fields[0]:value} return search_dict
def get_search_dict2(self): #實現多個欄位模糊匹配,欄位間是or的關係
q = Q() #Q,什麼條件都沒有
value = self.request.GET.get('search')
if value:
for filed in self.search_fields:
d ={"%s__contains" %filed:value}
q = Q(**d) |q
return q
#把複用介面方法變成共用方法, class GetView(BaseView): def get(self,requests): # get請求時 獲取傳遞過來的第幾頁資料 page = requests.GET.get('page') filter_dict = self.get_filter_dict() search_dict = self.get_search_dict()
search_q = self.get_search_dict2()
#增加過濾條件,獲取查詢結果 qs = self.model_class.bojects.filter(is_delete=0).filter(filter_dict).filter(**search_dict).filter(search_q) page_obj = Paginator(qs, 5) # 獲取第幾頁的資料 page_data = page_obj.get_page(page) # 用於儲存返回的dict型別資料 data_list = [] for data in page_data: # 通過 model_to_dict轉換成dict,exclude過濾哪些欄位 tmp_data = model_to_dict(data, fields=self.fields,exclude=self.exclude_fields) data_list.append(tmp_data) return JsonResponse({"code": 0, "data": data_list})

#老的views中只需傳入條件:

from .custom_view import GetView

#簡化程式碼 ,繼承
class SParameter(GetView):
    model_class = models.Parameter   #1-重寫類變數,指定操作的資料
    fields = ['name']                #2-指定返回name欄位
    exclude_fields = ['name']        #3-返回欄位過濾掉name欄位
    filter_fields = ['name']         #4-按照name進行過濾
    search_fields = ['name']         #5-按照name進行模糊匹配

#同時urls優化,在子專案下建立一個urls.py

#子urls引用custom_views邏輯
from
django.urls import path from .views import f_parameter,SParameter urlpatterns = [ # fbv path('f_parameter', f_parameter), # cbv # path('c_parameter', Parameter.as_view()), # 優化程式碼後cbv路由 path('s_parameter', SParameter.as_view()), ]

#老urls中再引用子專案下的urls

from django.urls import path,include
from example import urls

urlpatterns = [

    #通過include 將其他app的路由匯入進來
    #api是base目錄,每個example當中的路由都會加上api/
    path('api/',include(urls)),
]