分頁器相關知識點,請查看如下連接html
http://www.javashuo.com/article/p-bqfndgzo-cx.html前端
歸類前代碼數據庫
header_list = [] # 定製一個空別表 for field_or_func in self.get_new_list_display(): # 若是是多對多的 if callable(field_or_func): val = field_or_func(self, header=True) header_list.append(val) # header_list.append(field_or_func.__name__) # 若是是普通屬性 else: if field_or_func == "__str__": val = self.model._meta.model_name.upper() else: field_obj = self.model._meta.get_field(field_or_func) val = field_obj.verbose_name # 自定義屬性名 header_list.append(val) # 構建展現數據 new_data = [] for obj in queryset: temp = [] for field_or_func in self.get_new_list_display(): if callable(field_or_func): val = field_or_func(self, obj) # 獲取函數返回值,傳入obj進行從操做數據 elif not field_or_func == "__str__": from django.db.models.fields.related import ManyToManyField field_obj = self.model._meta.get_field(field_or_func) # 獲取模型對象 # 判斷是否爲多對多屬性 if type(field_obj) == ManyToManyField: raise Exception("list_display不能是多對多字段!") # 判斷是否有選擇屬性 if field_obj.choices: val = getattr(obj, "get_%s_display" % field_or_func)() # 調用這個方法,反射方法,調用方法獲取對應的內容 else: val = getattr(obj, field_or_func) if field_or_func in self.list_display_links: val = mark_safe("<a href='%s'>%s</a>" % (self.get_change_url(obj), val)) else: val = getattr(obj, field_or_func)() temp.append(val) # print(">>>>>>>>>>>>",temp) new_data.append(temp)
在原內容地方經過實例對象調用內容django
ruquset.GET.get("篩選內容",默認值=None) 即若是不寫默認值則爲空,這裏寫爲1 即,沒獲取到時候爲1app
獲取分好頁的數據(經過切片[開始:結束])ide
前端效果:函數
歸類後完整代碼url
from django.urls import path, re_path from app01.models import * from django.shortcuts import HttpResponse, render, redirect from django.utils.safestring import mark_safe from django.urls import reverse class ShowList(object): # def __init__(self, request, config_obj, queryset): self.request = request # 接收請求 self.config_obj = config_obj #接收自定義配置類 self.queryset = queryset #接收數據 self.pager_queryset = self.get_pager_queryset() # 實例分頁對象獲取內容 def get_pager_queryset(self): from stark.utils.page import Pagination # 導入本身寫的分頁包 current_page = self.request.GET.get("page", 1) # 當前操做頁 self.pagination = Pagination(self.request, current_page, self.queryset, per_page_num=self.config_obj.per_page_num or 5) queryset = self.queryset[self.pagination.start:self.pagination.end] return queryset def get_header(self): header_list = [] # 定製一個空別表 for field_or_func in self.config_obj.get_new_list_display(): # 替換成config_obj 代用,self 表明原自定義配置類 # 若是是多對多的 if callable(field_or_func): val = field_or_func(self, header=True) header_list.append(val) # header_list.append(field_or_func.__name__) # 若是是普通屬性 else: if field_or_func == "__str__": val = self.config_obj.model._meta.model_name.upper() else: field_obj = self.config_obj.model._meta.get_field(field_or_func) val = field_obj.verbose_name # 自定義屬性名 header_list.append(val) return header_list #f返回前端的內容 def get_body(self): # 構建展現數據 new_data = [] for obj in self.pager_queryset: temp = [] for field_or_func in self.config_obj.get_new_list_display(): if callable(field_or_func): val = field_or_func(self.config_obj, obj) # 獲取函數返回值,傳入obj進行從操做數據 # self 統一換成self.config_obj elif not field_or_func == "__str__": from django.db.models.fields.related import ManyToManyField field_obj = self.config_obj.model._meta.get_field(field_or_func) # 獲取模型對象 # 判斷是否爲多對多屬性 if type(field_obj) == ManyToManyField: raise Exception("list_display不能是多對多字段!") # 判斷是否有選擇屬性 if field_obj.choices: val = getattr(obj, "get_%s_display" % field_or_func)() # 調用這個方法,反射方法,調用方法獲取對應的內容 else: val = getattr(obj, field_or_func) if field_or_func in self.config_obj.list_display_links: val = mark_safe("<a href='%s'>%s</a>" % (self.config_obj.get_change_url(obj), val)) else: val = getattr(obj, field_or_func)() temp.append(val) # print(">>>>>>>>>>>>",temp) new_data.append(temp) return new_data #返回前端數據部分 class ModelStark(object): ''' 默認配置類 ''' list_display = ("__str__",) list_display_links = [] # 設置默認爲空 model_form_class = None # 設置默認爲無 per_page_num=None #設置接口 search_fields = [] #建立search_fidels接口 search_val = None # 默認讓search_val的值爲none def __init__(self, model): self.model = model self.model_name = self.model._meta.model_name self.app_label = self.model._meta.app_label # 反向解析當前訪問表的增刪改查URL def get_list_url(self): # 反向解析當前表的刪除的URL list_url = reverse("%s_%s_list" % (self.app_label, self.model_name)) return list_url def get_add_url(self, obj=None): # 反向解析當前表的刪除的URL add_url = reverse("%s_%s_add" % (self.app_label, self.model_name)) return add_url def get_delete_url(self, obj): # 反向解析當前表的刪除的URL delete_url = reverse("%s_%s_delete" % (self.app_label, self.model_name), args=(obj.pk,)) return delete_url def get_change_url(self, obj): # 反向解析當前表的change的URL change_url = reverse("%s_%s_change" % (self.app_label, self.model_name), args=(obj.pk,)) return change_url def get_new_list_display(self): temp = [] temp.extend(self.list_display) # 繼承原來的列表內容 temp.append(ModelStark.show_editbtn) # 注意傳過來的是屬性 temp.append(ModelStark.show_delbtn) # 注意傳過來的是屬性 temp.insert(0, ModelStark.show_checkbox) # temp.insert(1,self.show_checkbox()) # 同上不加括號,把方法名加入到列表方便掉用 return temp def show_checkbox(self, obj=None, header=False): # 展現選擇列 if header: return mark_safe("<input type='checkbox'>") return mark_safe("<input type='checkbox'>") def show_delbtn(self, obj=None, header=False): if header: return "刪除" return mark_safe("<a href='%s'>刪除</a>" % self.get_delete_url(obj)) def show_editbtn(self, obj=None, header=False): if header: return "編輯" return mark_safe("<a href='%s'>編輯</a>" % self.get_change_url(obj)) def get_search_condition(self, request): val = request.GET.get("q") # 獲取name q的內容 from django.db.models import Q # 導入Q 包 .進行或操做 q = Q() # 實例一個Q 對象 if val:# 若是進行了查詢操做 self.search_val = val q.connector = "or" # 更改q爲或操做 for field in self.search_fields: # ["title","price"] # 從接口中拿字段 print(field) # queryset=queryset.filter(Q(title__contains=val)|Q(price__contains=val)) q.children.append((field + "__contains", val)) # 利用小q進行模糊查詢,和拼接 # "__contains 模糊查詢" 即 title__contains=val 查詢 else: self.search_val = None return q def list_view(self, request): # print(self) # 當前訪問模型表對應的配置類對象 # print(self.model) # 當前訪問模型表 queryset = self.model.objects.all() print("+>>>>>>>", queryset) # 構建表頭 queryset=queryset.filter(self.get_search_condition(request)) show_list = ShowList(request, self, queryset) # 當前請求 ,當前操做的自定製配置類,當前全部數據 table_name = self.model._meta.verbose_name add_url = self.get_add_url() # print("<<<<<<<<<<<",new_data) return render(request, "stark/list_view.html", locals()) # data = self.model.objects.all() # print(data) # print("-------",self.list_display) # data_list=[] # dict1={} # for obj in data: # lis =[] # for msg in self.list_display: # lis.append(getattr(obj,msg)) # data_list.append(lis) # print("jjjjjjjjj",data_list) # return render(request, 'stark/list_view.html', { # "data_list":data_list, # "list_display":self.list_display # }) def get_model_form(self): # 建立獲取model_form 內容函數 from django.forms import ModelForm # 導入包 class BaseModelForm(ModelForm): # 建立modelform類,繼承modelform class Meta: # 建立可調用內容 model = self.model # 導入當前操做模型對象 fields = "__all__" # 獲取所有 return self.model_form_class or BaseModelForm # 若是有內容就傳入內容,沒有就走默認的Base的 # 有的時候須要從新寫class BasemodelForm類並繼承他 def add_view(self, request): # 視圖函數add_view BaseModelForm = self.get_model_form() # 經過get_model_form運行獲取類 if request.method == "GET": form_obj = BaseModelForm() # 實例化對象獲取內容 return render(request, "stark/add_view.html", locals()) # 傳到前端內容(屬性) else: form_obj = BaseModelForm(request.POST) # 向渲染的模型類中加入數據 if form_obj.is_valid(): # 判斷接收數據是否可用 form_obj.save() # 將數據保存到數據庫 return redirect(self.get_list_url()) # 跳轉 else: return render(request, "stark/add_view.html", locals()) def change_view(self, request, id): # 建立change_view路由 ,傳入request,id,經過反向解析獲取id BaseModelForm = self.get_model_form() # 經過方法獲取modelform類 edit_obj = self.model.objects.filter(pk=id).first() # 經過id獲取當前操做對象 if request.method == "GET": form_obj = BaseModelForm(instance=edit_obj) # 經過instance參數,進行控制爲傳入對象能夠到前端進行渲染 return render(request, "stark/change_view.html", locals()) else: form_obj = BaseModelForm(request.POST, instance=edit_obj) # 接收前端內容,instance對象,是內容進行覆蓋 if form_obj.is_valid(): form_obj.save() # 數據保存 return redirect(self.get_list_url()) else: return render(request, "stark/change_view.html", locals()) def delete_view(self, request, id): # 接收反向解析傳過來的id if request.method == "POST": self.model.objects.filter(pk=id).delete() # 接收id 刪除主鍵 return redirect(self.get_list_url()) # 跳轉 list_url = self.get_list_url() # 把展現界面傳過去.方便用戶取消 return render(request, "stark/delete_view.html", locals()) # 新建刪除html @property def get_urls(self): temp = [ path("", self.list_view, name="%s_%s_list" % (self.app_label, self.model_name)), path("add/", self.add_view, name="%s_%s_add" % (self.app_label, self.model_name)), re_path("(\d+)/change/", self.change_view, name="%s_%s_change" % (self.app_label, self.model_name)), re_path("(\d+)/delete/", self.delete_view, name="%s_%s_delete" % (self.app_label, self.model_name)), ] return (temp, None, None) class StarkSite: ''' stark全局類 ''' def __init__(self): self._registry = {} def register(self, model, admin_class=None, **options): admin_class = admin_class or ModelStark self._registry[model] = admin_class(model) def get_urls(self): # 動態爲註冊的模型類建立增刪改查URL temp = [] # {Book:ModelAdmin(Book),Publish:ModelAdmin(Publish)} for model, config_obj in self._registry.items(): # print("---->", model, config_obj) model_name = model._meta.model_name app_label = model._meta.app_label temp.append( path("%s/%s/" % (app_label, model_name), config_obj.get_urls) ) ''' path("stark/app01/book",self.list_view) path("stark/app01/book/add",self.add_view) path("stark/app01/publish",self.list_view) path("stark/app01/publish/add",self.add_view) ''' return temp @property def urls(self): return self.get_urls(), None, None site = StarkSite()
知識點:django中Q查詢的使用,實例化Q之後能夠進行更改內容且經過字符串進行修改spa
註冊接口內容3d
設置name=q進行form表單數據進行操做,經過if進行判斷若是有配置search_fidleds接口則顯示出搜索框,不然則不顯示搜索框
__contains進行數據模糊查詢
經過’啊’進行搜索
a