設計查頁面,主要展現兩部份內容,表頭部分和數據部分, 表頭經過遍歷list_display和默認要顯示的編輯和刪除字段。javascript
class ModelStark(object): """定製配置類""" list_display = [] def __init__(self, model, site): self.model = model self.site = site '''省略其餘代碼''' def list_view(self, request): print("self.model:", self.model) # self.model: <class 'app01.models.UserInfo'> print("list_display", self.list_display) # list_display ['pk', 'name', 'age'] data_list = self.model.objects.all() # 拿到對應表全部的對象 new_data_list = [] for obj in data_list: # 所查詢表中的一個個對象 temp = [] for field in self.list_display: # field爲一個個字段字符串 val = getattr(obj, field) # obj.name obj.age temp.append(val) new_data_list.append(temp) return render(request, "list_view.html", locals()) '''省略其餘代碼'''
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css"> </head> <body> <h4>數據列表</h4> <div class="container"> <div class="row"> <div class="col-md-9"> <table class="table table-bordered table-striped"> <thead></thead> <tbody> {% for data in new_data_list %} <tr> {% for item in data %} <td>{{ item }}</td> {% endfor %} </tr> {% endfor %} </tbody> </table> </div> </div> </div> </body> </html>
顯示效果:css
注意:html
若是list_display有值就按裏面的字段展現,若是沒有值按照默認的obj展現。java
app01/stark.py:python
# 自定義配置類 class UserConfig(ModelStark): # UserConfig是ModelStark的一個子類 list_display = ["pk", "name", "age"]
根據父類子類關係,從調用者類裏去找x,若是調用者中沒有x,去父類找:jquery
class A(object): x = 12 def func(self): print(self.x) class B(A): x = 5 b = B() b.func() # 5
data_list = self.model.objects.all() # 拿到對應表全部的對象 new_data_list = [] for obj in data_list: # 所查詢表中的一個個對象 temp = [] for field in self.list_display: # field爲一個個字段字符串 val = getattr(obj, field) # obj.name obj.age temp.append(val) new_data_list.append(temp)
字符串不是變量名稱,沒法進行點字符串操做。django
class Person(object): def __init__(self, name): self.name = name alex = Person("alex") s = "name" # 直接alex.s 或者alex."name"都是取不到值的 print(getattr(alex, s)) # alex
from django.conf.urls import url from django.shortcuts import HttpResponse,render class ModelStark(object): """定製配置類""" list_display = [] def __init__(self, model, site): self.model = model self.site = site def add(self, request): return HttpResponse("add") def delete(self, request, id): return HttpResponse("delete") def change(self, request, id): return HttpResponse("change") def list_view(self, request): print("self.model:", self.model) # self.model: <class 'app01.models.UserInfo'> print("list_display", self.list_display) # list_display ['pk', 'name', 'age'] data_list = self.model.objects.all() # 拿到對應表全部的對象 new_data_list = [] for obj in data_list: # 所查詢表中的一個個對象 temp = [] for field in self.list_display: # field爲一個個字段字符串 ['pk', 'name', 'age', edit] if callable(field): # 用於判斷是不是函數,可調用的是方法,不可調用的是屬性 val = field(self, obj) # edit(self, obj) obj是當前正在處理的這個記錄 else: val = getattr(obj, field) # 必定要是屬性才能這麼去調用, obj.name obj.age temp.append(val) new_data_list.append(temp) return render(request, "list_view.html", locals()) def get_urls_2(self): temp = [] # 用name取別名app名+model名+操做名能夠保證別名不會重複 model_name = self.model._meta.model_name app_label = self.model._meta.app_label temp.append(url(r"^add/", self.add, name="%s_%s_add" % (app_label, model_name))) temp.append(url(r"^(\d+)/delete/", self.delete, name="%s_%s_delete" % (app_label, model_name))) temp.append(url(r"^(\d+)/change/", self.change, name="%s_%s_change" % (app_label, model_name))) temp.append(url(r"^$", self.list_view, name="%s_%s_list" % (app_label, model_name))) return temp @property def urls_2(self): return self.get_urls_2(), None, None # [], None, None class StarkSite(object): """site單例類""" def __init__(self): self._registry = {} def register(self, model, stark_class=None, **options): """註冊""" if not stark_class: # 若是註冊的時候沒有自定義配置類,執行 stark_class = ModelStark # 配置類 # 將配置類對象加到_registry字典中,鍵爲模型類 self._registry[model] = stark_class(model, self) # _registry={'model':admin_class(model)} def get_urls(self): """構造一層url""" temp = [] for model, stark_class_obj in self._registry.items(): # model:一個模型表 # stark_class_obj:當前模型表相應的配置類對象 model_name = model._meta.model_name app_label = model._meta.app_label # 分發增刪改查 temp.append(url(r"^%s/%s/" % (app_label, model_name), stark_class_obj.urls_2)) """ path('app01/userinfo/',UserConfig(Userinfo,site).urls2), path('app01/book/',ModelStark(Book,site).urls2), """ return temp @property def urls(self): return self.get_urls(), None, None site = StarkSite() # 單例對象
from app01 import models from stark.service.stark import site, ModelStark from django.utils.safestring import mark_safe from django.urls import reverse # 自定義配置類 class UserConfig(ModelStark): # UserConfig是ModelStark的一個子類 def edit(self, obj): # 方法一: # return mark_safe("<a href='/stark/app01/userinfo/%s/change'>編輯</a>" % obj.pk) # 方法二:前面不加/就是和前面的路徑拼接 # return mark_safe("<a href='%s/change'>編輯</a>" % obj.pk) # 方法三:反向解析 model_name = self.model._meta.model_name app_label = self.model._meta.app_label # _url = reverse("%s_%s_add" % (app_label, model_name)) # print("_url", _url) # _url /stark/app01/userinfo/add/ # stark/app01/userinfo/(/d+)/change _url = reverse("%s_%s_change" % (app_label, model_name), args=(obj.pk, )) print("_url", _url) # _url /stark/app01/userinfo/3/change/ return mark_safe("<a href='%s/change'>編輯</a>" % obj.pk) def deletes(self, obj): model_name = self.model._meta.model_name app_label = self.model._meta.app_label _url = reverse("%s_%s_delete" % (app_label, model_name), args=(obj.pk, )) print("_url", _url) # _url /stark/app01/userinfo/3/change/ return mark_safe("<a href='%s/change'>刪除</a>" % obj.pk) list_display = ["pk", "name", "age", edit, deletes] site.register(models.UserInfo, UserConfig) site.register(models.Book) print("_registry", site._registry)
注意:bootstrap
if callable(field): # 用於判斷是不是函數,可調用的是方法,不可調用的是屬性 val = field(self) else: val = getattr(obj, field) # 必定要是屬性才能這麼去調用, obj.name obj.age temp.append(val)
class Person(object): def __init__(self, name): self.name = name def eat(self): print(self) print("eat.....") # 實例方法 egon = Person("egon") egon.eat() """ <__main__.Person object at 0x10401ae48> eat..... """ # 函數 Person.eat(123) """ 123 eat..... """
from django.utils.safestring import mark_safe # 自定義配置類 class UserConfig(ModelStark): # UserConfig是ModelStark的一個子類 def edit(self): return mark_safe("<a>編輯</a>") list_display = ["pk", "name", "age", edit]
顯示效果:app
startk/service/stark.py中的list_view函數中,在判斷filed是函數時,給這個函數還傳入一個obj也就是當前正在處理的記錄對象:ide
class ModelStark(object): def list_view(self, request): for obj in data_list: # 所查詢表中的一個個對象 temp = [] for field in self.list_display: # field爲一個個字段字符串 ['pk', 'name', 'age', edit] if callable(field): # 用於判斷是不是函數,可調用的是方法,不可調用的是屬性 val = field(self, obj) # edit(self, obj) obj是當前正在處理的這個記錄 else: val = getattr(obj, field) # 必定要是屬性才能這麼去調用, obj.name obj.age temp.append(val) new_data_list.append(temp)
前面已經實現實現了編輯按鈕,如今須要在app01/stark.py中爲edit方法返回值配好返回的a標籤的href路徑:
from app01 import models from stark.service.stark import site, ModelStark from django.utils.safestring import mark_safe # 自定義配置類 class UserConfig(ModelStark): # UserConfig是ModelStark的一個子類 def edit(self, obj): # 方法一: # return mark_safe("<a href='/stark/app01/userinfo/%s/change'>編輯</a>" % obj.pk) # 方法二:前面不加/就是和前面的路徑拼接 return mark_safe("<a href='%s/change'>編輯</a>" % obj.pk) list_display = ["pk", "name", "age", edit]
顯示效果:
https://www.cnblogs.com/yuanchenqi/articles/7629939.html
首先給urls用name添加別名:app名+model名+操做名能夠保證別名不重複
class ModelStark(object): """定製配置類""" '''省略內容''' def get_urls_2(self): temp = [] # 用name取別名app名+model名+操做名能夠保證別名不會重複 model_name = self.model._meta.model_name app_label = self.model._meta.app_label temp.append(url(r"^add/", self.add, name="%s_%s_add" % (app_label, model_name))) temp.append(url(r"^(\d+)/delete/", self.delete, name="%s_%s_delete" % (app_label, model_name))) temp.append(url(r"^(\d+)/change/", self.change, name="%s_%s_change" % (app_label, model_name))) temp.append(url(r"^$", self.list_view, name="%s_%s_list" % (app_label, model_name))) return temp
路由效果以下所示:
再在app01/stark.py中edit方法以反向解析解析路徑:
from app01 import models from stark.service.stark import site, ModelStark from django.utils.safestring import mark_safe from django.urls import reverse # 自定義配置類 class UserConfig(ModelStark): # UserConfig是ModelStark的一個子類 def edit(self, obj): # 方法一: # return mark_safe("<a href='/stark/app01/userinfo/%s/change'>編輯</a>" % obj.pk) # 方法二:前面不加/就是和前面的路徑拼接 # return mark_safe("<a href='%s/change'>編輯</a>" % obj.pk) # 方法三:反向解析 model_name = self.model._meta.model_name app_label = self.model._meta.app_label # _url = reverse("%s_%s_add" % (app_label, model_name)) # print("_url", _url) # _url /stark/app01/userinfo/add/ # stark/app01/userinfo/(/d+)/change _url = reverse("%s_%s_change" % (app_label, model_name), args=(obj.pk, )) print("_url", _url) # _url /stark/app01/userinfo/3/change/ return mark_safe("<a href='%s/change'>編輯</a>" % obj.pk) list_display = ["pk", "name", "age", edit] site.register(models.UserInfo, UserConfig)
點擊按鈕顯示效果同上。
class UserConfig(ModelStark): # UserConfig是ModelStark的一個子類 def edit(self, obj):... def deletes(self, obj): model_name = self.model._meta.model_name app_label = self.model._meta.app_label _url = reverse("%s_%s_delete" % (app_label, model_name), args=(obj.pk, )) print("_url", _url) # _url /stark/app01/userinfo/3/change/ return mark_safe("<a href='%s/change'>刪除</a>" % obj.pk) list_display = ["pk", "name", "age", edit, deletes]
顯示效果以下:
def checkbox(self, obj): """複選框""" return mark_safe("<input type='checkbox'>")
顯示效果:
class ModelStark(object): """默認類,定製配置類""" list_display = ["__str__",] def __init__(self, model, site): self.model = model self.site = site # 刪除、編輯,複選框 def edit(self, obj): """編輯""" # 方法三:反向解析 model_name = self.model._meta.model_name app_label = self.model._meta.app_label _url = reverse("%s_%s_change" % (app_label, model_name), args=(obj.pk, )) print("_url", _url) return mark_safe("<a href='%s/change'>編輯</a>" % obj.pk) def deletes(self, obj): """刪除""" model_name = self.model._meta.model_name app_label = self.model._meta.app_label _url = reverse("%s_%s_delete" % (app_label, model_name), args=(obj.pk, )) print("_url", _url) return mark_safe("<a href='%s/change'>刪除</a>" % obj.pk) def checkbox(self, obj): """複選框""" return mark_safe("<input type='checkbox'>") '''代碼省略''' def new_list_display(self): """返回新的列表""" temp = [] temp.append(ModelStark.checkbox) # 在列表中放一個checkbox名字 temp.extend(self.list_display) # 擴展進一個列表["pk","name","age"] temp.append(ModelStark.edit) # edit函數名 temp.append(ModelStark.deletes) # deletes函數名 return temp # 返回新的列表 def list_view(self, request): """循環展現""" print("self.model:", self.model) # self.model: <class 'app01.models.UserInfo'> print("list_display", self.list_display) # list_display ['pk', 'name', 'age'] data_list = self.model.objects.all() # 拿到對應表全部的對象 """構建表單數據""" new_data_list = [] for obj in data_list: temp = [] for field in self.new_list_display(): # ["__str__", ] ["pk","name","age",edit] if callable(field): val = field(self, obj) else: val = getattr(obj, field) temp.append(val) new_data_list.append(temp) return render(request, "list_view.html", locals())
將這些函數從自定義配置類(app01/stark.py裏的UserConfig)剪切到默認類(stark/service/stark.py裏的ModelStark),剩下的app01/stark.py代碼以下所示:
from app01 import models from stark.service.stark import site, ModelStark class UserConfig(ModelStark): # UserConfig是ModelStark的一個子類 """自定義配置類""" list_display = ["pk", "name", "age"] site.register(models.UserInfo, UserConfig) class BookConfig(ModelStark): list_display = ['pk', 'title'] site.register(models.Book) print("_registry", site._registry)
能夠注意到自定義配置類的list_display已經沒有了edit,delete等函數, 所以須要返回新的列表。
class ModelStark(object): '''省略代碼'''' def new_list_display(self): """返回新的列表""" temp = [] temp.append(ModelStark.checkbox) # 在列表中放一個checkbox名字 temp.extend(self.list_display) # 擴展進一個列表["pk","name","age"] temp.append(ModelStark.edit) # edit函數名 temp.append(ModelStark.deletes) # deletes函數名 return temp # 返回新的列表
在list_view中調用新的的列表:
def list_view(self, request): """構建表單數據""" new_data_list = [] for obj in data_list: temp = [] for field in self.new_list_display(): # ["__str__", ] ["pk","name","age",edit] if callable(field): val = field(self, obj) else: val = getattr(obj, field) temp.append(val) new_data_list.append(temp) return render(request, "list_view.html", locals())
##################stark/service/stark.py############### class ModelStark(object): """默認類,定製配置類""" list_display = ["__str__",] ##################app01/stark.py################## class UserConfig(ModelStark): # UserConfig是ModelStark的一個子類 """自定義配置類""" list_display = ["pk", "name", "age"] class BookConfig(ModelStark): list_display = ['pk', 'title']
這裏涉及到類的__str__方法使用,示例以下:
class Persoon(object): def __init__(self, name): self.name = name def __str__(self): return self.name alex = Persoon("alex") print(alex.__str__) print(alex.__str__()) print(str(alex)) """' <bound method Persoon.__str__ of <__main__.Persoon object at 0x10401ae48>> alex alex """
# -*- coding:utf-8 -*- __author__ = 'Qiushi Huang' from django.conf.urls import url from django.shortcuts import HttpResponse, render from django.utils.safestring import mark_safe from django.urls import reverse class ModelStark(object): """默認類,定製配置類""" list_display = ["__str__",] def __init__(self, model, site): self.model = model self.site = site # 刪除、編輯,複選框 def edit(self, obj=None, header=False): """編輯""" if header: # 若是是表頭顯示操做 return "操做" # 方法三:反向解析 model_name = self.model._meta.model_name app_label = self.model._meta.app_label _url = reverse("%s_%s_change" % (app_label, model_name), args=(obj.pk, )) print("_url", _url) return mark_safe("<a href='%s/change'>編輯</a>" % obj.pk) def deletes(self, obj=None, header=False): """刪除""" if header: # 若是是表頭顯示操做 return "操做" model_name = self.model._meta.model_name app_label = self.model._meta.app_label _url = reverse("%s_%s_delete" % (app_label, model_name), args=(obj.pk, )) print("_url", _url) return mark_safe("<a href='%s/change'>刪除</a>" % obj.pk) def checkbox(self, obj=None, header=False): """複選框""" if header: # 若是是表頭顯示操做 return mark_safe("<input id='choice' type='checkbox'>") return mark_safe("<input class='choice_item' type='checkbox'>") def add(self, request): return HttpResponse("add") def delete(self, request, id): return HttpResponse("delete") def change(self, request, id): return HttpResponse("change") def new_list_display(self): """返回新的列表""" temp = [] temp.append(ModelStark.checkbox) # 在列表中放一個checkbox名字 temp.extend(self.list_display) # 擴展進一個列表["pk","name","age"] temp.append(ModelStark.edit) # edit函數名 temp.append(ModelStark.deletes) # deletes函數名 return temp # 返回新的列表 def list_view(self, request): """循環展現""" print("self.model:", self.model) # self.model: <class 'app01.models.UserInfo'> print("list_display", self.list_display) # list_display ['pk', 'name', 'age'] list_display ['__str__'] data_list = self.model.objects.all() # 拿到對應表全部的對象 """構建表頭""" header_list = [] print("header", self.new_list_display()) # [checkbox ,"__str__", edit ,deletes] for field in self.new_list_display(): if callable(field): # 若是是函數 val = field(self, header=True) header_list.append(val) else: # 若是是字符串 if field == "__str__": header_list.append(self.model._meta.model_name.upper()) # 當前模型表名 else: # 若是不是"__str__" # header_list.append(field) val = self.model._meta.get_field(field).verbose_name header_list.append(val) """構建表單數據""" new_data_list = [] for obj in data_list: temp = [] for field in self.new_list_display(): # ["__str__", ] ["pk","name","age",edit] if callable(field): val = field(self, obj) else: val = getattr(obj, field) temp.append(val) new_data_list.append(temp) return render(request, "list_view.html", locals()) def get_urls_2(self): temp = [] # 用name取別名app名+model名+操做名能夠保證別名不會重複 model_name = self.model._meta.model_name app_label = self.model._meta.app_label temp.append(url(r"^add/", self.add, name="%s_%s_add" % (app_label, model_name))) temp.append(url(r"^(\d+)/delete/", self.delete, name="%s_%s_delete" % (app_label, model_name))) temp.append(url(r"^(\d+)/change/", self.change, name="%s_%s_change" % (app_label, model_name))) temp.append(url(r"^$", self.list_view, name="%s_%s_list" % (app_label, model_name))) return temp @property def urls_2(self): return self.get_urls_2(), None, None # [], None, None class StarkSite(object): """site單例類""" def __init__(self): self._registry = {} def register(self, model, stark_class=None, **options): """註冊""" if not stark_class: # 若是註冊的時候沒有自定義配置類,執行 stark_class = ModelStark # 配置類 # 將配置類對象加到_registry字典中,鍵爲模型類 self._registry[model] = stark_class(model, self) # _registry={'model':admin_class(model)} def get_urls(self): """構造一層url""" temp = [] for model, stark_class_obj in self._registry.items(): # model:一個模型表 # stark_class_obj:當前模型表相應的配置類對象 model_name = model._meta.model_name app_label = model._meta.app_label # 分發增刪改查 temp.append(url(r"^%s/%s/" % (app_label, model_name), stark_class_obj.urls_2)) """ path('app01/userinfo/',UserConfig(Userinfo,site).urls2), path('app01/book/',ModelStark(Book,site).urls2), """ return temp @property def urls(self): return self.get_urls(), None, None site = StarkSite() # 單例對象
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css"> <script src="/static/js/jquery-1.12.4.min.js"></script> </head> <body> <h4>數據列表</h4> <div class="container"> <div class="row"> <div class="col-md-9"> <table class="table table-bordered table-striped"> <thead> <tr> {% for item in header_list %} <th>{{ item }}</th> {% endfor %} </tr> </thead> <tbody> {% for data in new_data_list %} <tr> {% for item in data %} <td>{{ item }}</td> {% endfor %} </tr> {% endfor %} </tbody> </table> </div> </div> </div> <script> // 複選框全選 $("#choice").click(function () { if($(this).prop("checked")) { // 若是是選中狀態 $(".choice_item").prop("checked", true); } else { $(".choice_item").prop("checked", false) } }) </script> </body> </html>
__name__是標識模塊的名字的一個系統變量;__main__
通常做爲函數的入口,相似於C語言,尤爲在大型工程中,經常有if __name__ == "__main__":
來代表整個工程開始運行的入口。
def foo(): return print(foo.__name__) # foo
def list_view(self, request): """構建表頭""" header_list = [] print("header", self.new_list_display()) # [checkbox ,"__str__", edit ,deletes] for field in self.new_list_display(): if callable(field): # 若是是函數 val = field(self, header=True) header_list.append(val) else: # 若是是字符串 if field == "__str__": header_list.append(self.model._meta.model_name.upper()) # 當前模型表名 else: # 若是不是"__str__" header_list.append(field)
當callable判斷field是函數時,給函數傳參數header=True。修改編輯、刪除、選擇函數:
# 刪除、編輯,複選框 def edit(self, obj=None, header=False): """編輯""" if header: # 若是是表頭顯示操做 return "操做" # 方法三:反向解析 model_name = self.model._meta.model_name app_label = self.model._meta.app_label _url = reverse("%s_%s_change" % (app_label, model_name), args=(obj.pk, )) print("_url", _url) return mark_safe("<a href='%s/change'>編輯</a>" % obj.pk) def deletes(self, obj=None, header=False): """刪除""" if header: # 若是是表頭顯示操做 return "操做" model_name = self.model._meta.model_name app_label = self.model._meta.app_label _url = reverse("%s_%s_delete" % (app_label, model_name), args=(obj.pk, )) print("_url", _url) return mark_safe("<a href='%s/change'>刪除</a>" % obj.pk) def checkbox(self, obj=None, header=False): """複選框""" if header: # 若是是表頭顯示操做 return "選擇" return mark_safe("<input type='checkbox'>")
顯示效果:
def list_view(self, request): """構建表頭""" header_list = [] print("header", self.new_list_display()) # [checkbox ,"__str__", edit ,deletes] for field in self.new_list_display(): if callable(field): # 若是是函數 val = field(self, header=True) header_list.append(val) else: # 若是是字符串 if field == "__str__": header_list.append(self.model._meta.model_name.upper()) # 當前模型表名 else: # 若是不是"__str__" # header_list.append(field) val = self.model._meta.get_field(field).verbose_name header_list.append(val)
而後在models.py中爲字段添加verbose_name屬性
class UserInfo(models.Model): name = models.CharField(verbose_name="姓名", max_length=32) age = models.IntegerField(verbose_name="年齡") def __str__(self): return self.name class Book(models.Model): title = models.CharField(verbose_name="書名",max_length=32) def __str__(self): return self.title
顯示效果:
注意在這裏app01/stark.py中的list_display是不能添加「pk」的
class UserConfig(ModelStark): # UserConfig是ModelStark的一個子類 """自定義配置類""" list_display = ["name", "age"] site.register(models.UserInfo, UserConfig) class BookConfig(ModelStark): list_display = ['title'] site.register(models.Book) print("_registry", site._registry)
由於它的主鍵是"id",「pk」只能是在查詢的時候使用。且若是添加「id」的話,這個值也沒法改成中文。
class UserConfig(ModelStark): # UserConfig是ModelStark的一個子類 """自定義配置類""" list_display = ["id", "name", "age"]
顯示效果:
將表頭改成複選框,並給一個id:
def checkbox(self, obj=None, header=False): """複選框""" if header: # 若是是表頭顯示操做 return mark_safe("<input id='choice' type='checkbox'>") return mark_safe("<input class='choice_item' type='checkbox'>")
複選框點擊全選事件:
<script> // 複選框全選 $("#choice").click(function () { if($(this).prop("checked")) { // 若是是選中狀態 $(".choice_item").prop("checked", true); } else { $(".choice_item").prop("checked", false) } }) </script>
注意這裏使用js中的prop()方法來查看複選框是否選中,或設置複選框爲選中或未選中狀態。
class ModelStark(object): '''其餘代碼省略''' def new_list_display(self): """返回新的列表""" temp = [] temp.append(ModelStark.checkbox) # 在列表中放一個checkbox名字 temp.extend(self.list_display) # 擴展進一個列表["pk","name","age"] if not self.list_display_links: # 若是沒有值 temp.append(ModelStark.edit) # temp.append(ModelStark.edit) # edit函數名 temp.append(ModelStark.deletes) # deletes函數名 return temp # 返回新的列表 def list_view(self, request): """循環展現""" print("self.model:", self.model) # self.model: <class 'app01.models.UserInfo'> print("list_display", self.list_display) # list_display ['pk', 'name', 'age'] list_display ['__str__'] data_list = self.model.objects.all() # 拿到對應表全部的對象 """構建表頭""" header_list = [] print("header", self.new_list_display()) # [checkbox ,"__str__", edit ,deletes] for field in self.new_list_display(): if callable(field): # 若是是函數 val = field(self, header=True) header_list.append(val) else: # 若是是字符串 if field == "__str__": header_list.append(self.model._meta.model_name.upper()) # 當前模型表名 else: # 若是不是"__str__" # header_list.append(field) val = self.model._meta.get_field(field).verbose_name header_list.append(val) """構建表單數據""" new_data_list = [] for obj in data_list: temp = [] for field in self.new_list_display(): # ["__str__", ] ["pk","name","age",edit] if callable(field): val = field(self, obj) else: val = getattr(obj, field) if field in self.list_display_links: model_name = self.model._meta.model_name app_label = self.model._meta.app_label _url = reverse("%s_%s_change" % (app_label, model_name), args=(obj.pk,)) val = mark_safe("<a href='%s'>%s</a>" % (_url, val)) temp.append(val) new_data_list.append(temp) return render(request, "list_view.html", locals())
再也不拼接edit函數名,直接經過點擊普通字段進入編輯頁面。在構建表單數據時,判斷字段是否在list_display_links中,若是在的話經過反向解析生成a標籤指向的地址。
再在app01/stark.py的自定義配置類添加list_display_links:
class UserConfig(ModelStark): # UserConfig是ModelStark的一個子類 """自定義配置類""" list_display = ["id", "name", "age"] list_display_links = ["name"] site.register(models.UserInfo, UserConfig) class BookConfig(ModelStark): list_display = ['title'] list_display_links = ["title"]
顯示效果:
class ModelStark(object): def new_list_display(self): """返回新的列表""" temp = [] temp.append(ModelStark.checkbox) # 在列表中放一個checkbox名字 temp.extend(self.list_display) # 擴展進一個列表["pk","name","age"] if not self.list_display_links: # 若是沒有值 temp.append(ModelStark.edit) # temp.append(ModelStark.edit) # edit函數名 temp.append(ModelStark.deletes) # deletes函數名 return temp # 返回新的列表 def get_change_url(self,obj): model_name = self.model._meta.model_name app_label = self.model._meta.app_label _url = reverse("%s_%s_change" % (app_label, model_name), args=(obj.pk,)) return _url def get_delete_url(self, obj): model_name = self.model._meta.model_name app_label = self.model._meta.app_label _url = reverse("%s_%s_delete" % (app_label, model_name), args=(obj.pk,)) return _url def get_add_url(self): model_name = self.model._meta.model_name app_label = self.model._meta.app_label _url = reverse("%s_%s_add" % (app_label, model_name)) return _url def get_list_url(self):.....
將刪除、編輯、複選框等函數內的url拼接代碼替換後:
# -*- coding:utf-8 -*- __author__ = 'Qiushi Huang' from django.conf.urls import url from django.shortcuts import HttpResponse, render from django.utils.safestring import mark_safe from django.urls import reverse class ModelStark(object): """默認類,定製配置類""" list_display = ["__str__",] list_display_links = [] def __init__(self, model, site): self.model = model self.site = site # 刪除、編輯,複選框 def edit(self, obj=None, header=False): """編輯""" if header: # 若是是表頭顯示操做 return "操做" _url = self.get_change_url(obj) return mark_safe("<a href='%s'>編輯</a>" % _url) def deletes(self, obj=None, header=False): """刪除""" if header: # 若是是表頭顯示操做 return "操做" _url = self.get_delete_url(obj) # return mark_safe("<a href='%s/change'>刪除</a>" % obj.pk) return mark_safe("<a href='%s/'>刪除</a>" % _url) def checkbox(self, obj=None, header=False): """複選框""" if header: # 若是是表頭顯示操做 return mark_safe("<input id='choice' type='checkbox'>") return mark_safe("<input class='choice_item' type='checkbox'>") def add_view(self, request): return HttpResponse("add") def delete_view(self, request, id): return HttpResponse("delete") def change_view(self, request, id): return HttpResponse("change") def new_list_display(self): """返回新的列表""" temp = [] temp.append(ModelStark.checkbox) # 在列表中放一個checkbox名字 temp.extend(self.list_display) # 擴展進一個列表["pk","name","age"] if not self.list_display_links: # 若是沒有值 temp.append(ModelStark.edit) # temp.append(ModelStark.edit) # edit函數名 temp.append(ModelStark.deletes) # deletes函數名 return temp # 返回新的列表 def get_change_url(self,obj): model_name = self.model._meta.model_name app_label = self.model._meta.app_label _url = reverse("%s_%s_change" % (app_label, model_name), args=(obj.pk,)) return _url def get_delete_url(self, obj): model_name = self.model._meta.model_name app_label = self.model._meta.app_label _url = reverse("%s_%s_delete" % (app_label, model_name), args=(obj.pk,)) return _url def get_add_url(self): model_name = self.model._meta.model_name app_label = self.model._meta.app_label _url = reverse("%s_%s_add" % (app_label, model_name)) return _url def get_list_url(self): model_name = self.model._meta.model_name app_label = self.model._meta.app_label _url = reverse("%s_%s_list" % (app_label, model_name)) return _url def list_view(self, request): """循環展現""" print("self.model:", self.model) # self.model: <class 'app01.models.UserInfo'> print("list_display", self.list_display) # list_display ['pk', 'name', 'age'] list_display ['__str__'] data_list = self.model.objects.all() # 拿到對應表全部的對象 """構建表頭""" header_list = [] print("header", self.new_list_display()) # [checkbox ,"__str__", edit ,deletes] for field in self.new_list_display(): if callable(field): # 若是是函數 val = field(self, header=True) header_list.append(val) else: # 若是是字符串 if field == "__str__": header_list.append(self.model._meta.model_name.upper()) # 當前模型表名 else: # 若是不是"__str__" # header_list.append(field) val = self.model._meta.get_field(field).verbose_name header_list.append(val) """構建表單數據""" new_data_list = [] for obj in data_list: temp = [] for field in self.new_list_display(): # ["__str__", ] ["pk","name","age",edit] if callable(field): val = field(self, obj) else: val = getattr(obj, field) if field in self.list_display_links: # _url = reverse("%s_%s_change" % (app_label, model_name), args=(obj.pk,)) _url = self.get_change_url(obj) val = mark_safe("<a href='%s'>%s</a>" % (_url, val)) temp.append(val) new_data_list.append(temp) # 構建一個查看url add_url = self.get_add_url() return render(request, "list_view.html", locals()) def get_urls_2(self): temp = [] # 用name取別名app名+model名+操做名能夠保證別名不會重複 model_name = self.model._meta.model_name app_label = self.model._meta.app_label temp.append(url(r"^add/", self.add_view, name="%s_%s_add" % (app_label, model_name))) temp.append(url(r"^(\d+)/delete/", self.delete_view, name="%s_%s_delete" % (app_label, model_name))) temp.append(url(r"^(\d+)/change/", self.change_view, name="%s_%s_change" % (app_label, model_name))) temp.append(url(r"^$", self.list_view, name="%s_%s_list" % (app_label, model_name))) return temp @property def urls_2(self): return self.get_urls_2(), None, None # [], None, None class StarkSite(object): """site單例類""" def __init__(self): self._registry = {} def register(self, model, stark_class=None, **options): """註冊""" if not stark_class: # 若是註冊的時候沒有自定義配置類,執行 stark_class = ModelStark # 配置類 # 將配置類對象加到_registry字典中,鍵爲模型類 self._registry[model] = stark_class(model, self) # _registry={'model':admin_class(model)} def get_urls(self): """構造一層url""" temp = [] for model, stark_class_obj in self._registry.items(): # model:一個模型表 # stark_class_obj:當前模型表相應的配置類對象 model_name = model._meta.model_name app_label = model._meta.app_label # 分發增刪改查 temp.append(url(r"^%s/%s/" % (app_label, model_name), stark_class_obj.urls_2)) """ path('app01/userinfo/',UserConfig(Userinfo,site).urls2), path('app01/book/',ModelStark(Book,site).urls2), """ return temp @property def urls(self): return self.get_urls(), None, None site = StarkSite() # 單例對象