一、数据列表

  设计查页面,主要展示两部分内容,表头部分和数据部分, 表头通过遍历list_display和默认要显示的编辑和删除字段。

1、数据构建

(1)service/stark.py,后台数据构建

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()) '''省略其他代码'''

(2)list_view.html模板展示

<!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>

  显示效果:

  

注意:

(1)由于UserConfig类是ModelStark类的子类,且两边都有list_display变量。

  如果list_display有值就按里面的字段展示,如果没有值按照默认的obj展示。

app01/stark.py:

# 自定义配置类
class UserConfig(ModelStark): # UserConfig是ModelStark的一个子类
list_display = ["pk", "name", "age"]

  根据父类子类关系,从调用者类里去找x,如果调用者中没有x,去父类找:

class A(object):
x = 12 def func(self):
print(self.x) class B(A):
x = 5 b = B()
b.func() # 5

(2)字符串找对象的属性,反射

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)
 

  字符串不是变量名称,无法进行点字符串操作。

class Person(object):
def __init__(self, name):
self.name = name alex = Person("alex") s = "name" # 直接alex.s 或者alex."name"都是取不到值的
print(getattr(alex, s)) # alex

2、编辑按钮构建

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() # 单例对象

/stark/service/stark.py

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)

app01/stark.py

注意:

(1)利用callable方法判断是函数还是属性

if callable(field):   # 用于判断是否是函数,可调用的是方法,不可调用的是属性
val = field(self)
else:
val = getattr(obj, field) # 一定要是属性才能这么去调用, obj.name obj.age
temp.append(val)

(2)区分类的实例方法与函数调用及self参数

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.....
"""

(3)阻止<a>编辑</a>转义

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]

  显示效果:

  

(4)实现点击编辑进入编辑页面

  startk/service/stark.py中的list_view函数中,在判断filed是函数时,给这个函数还传入一个obj也就是当前正在处理的记录对象:

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]

  显示效果:

  

(5)用反向解析实现路径返回

  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)

  点击按钮显示效果同上。

(6)添加删除功能

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]

  显示效果如下:

  

(7)添加复选框按钮

def checkbox(self, obj):
"""复选框"""
return mark_safe("<input type='checkbox'>")

  显示效果:

  

二、构建表头并应用于所有列表对象

1、编辑编辑、删除、复选框函数,同时要实现每个表都能实现这些操作

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())

(1)不同的表都需要有这些按钮功能

  将这些函数从自定义配置类(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)

(2)self.list_display里现在只剩下普通字段,需要拼接出新的列表

  可以注意到自定义配置类的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())

(3)不同的表具有不同的自定义配置类,每个的list_display都不相同,对应表取对应的list_display

##################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
"""

(4)根据models.py中模型是否具有def __str__(self),页面上字段显示不同

  

  

2、构建表头

# -*- 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() # 单例对象

service/stark.py

<!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>

list_view.html

(1)__name__

  __name__是标识模块的名字的一个系统变量;__main__一般作为函数的入口,类似于C语言,尤其在大型工程中,常常有if __name__ == "__main__":来表明整个工程开始运行的入口。

def foo():
return print(foo.__name__) # foo

(2)将表头自定义函数显示改为中文

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'>")

  显示效果:

  

(3)将普通字段修改为中文

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"]

  显示效果:

  

(4)复选框点击全选事件

  将表头改为复选框,并给一个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()方法来查看复选框是否选中,或设置复选框为选中或未选中状态。

  

三、设计list_display_links

1、定制列可以点击跳转

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())

service/stark.py改动的部分

  不再拼接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"]

  显示效果:

  

2、将获取的应用名、模型名组成url定义为函数

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() # 单例对象

service/stark.py

stark——查看页面编辑删除按钮的更多相关文章

  1. selenium依次点击页面的删除按钮

    需要依次点击页面的删除按钮,如下图: @Test public static void FaBu() { TestMenuJump.jumpExam(driver); TestMenuJump.jum ...

  2. [App Store Connect帮助]二、 添加、编辑和删除用户(2)查看并编辑您的个人帐户

    您可以在 App Store Connect 的“编辑个人资料”中查看和编辑个人信息.如果您的 Apple ID 与多个帐户相关联,您可以在您的用户帐户之间切换. 查看您的个人帐户 在任意 App S ...

  3. ajax 实现加载页面、删除、查看详细信息,以及bootstrap网页的美化

      由于有些的程序员可能不是很会Photoshop,所以为了美化页面,我们可以借助工具bootstrap,实现起来相对就要比之前做的美观一些, 今天我用bootstrap把之前做的显示表格进行了一下美 ...

  4. GridView中的编辑和删除按钮,执行更新和删除代码之前的更新提示或删除提示

    在GridView中,可以通过设计界面GridViewr任务->编辑列->CommandField,很简单的添加的编辑和删除按钮 在前台源码中,可以看到GridView自动生成了两个列. ...

  5. 【HTML5】页面点击按钮添加一行 删除一行 全选 反选 全不选

    页面点击按钮添加一行    删除一行   全选   反选  全不选 页面效果图如下 html页面代码 <!DOCTYPE html> <html> <head> & ...

  6. el-table中操作一栏怎么根据当前行的信息显示编辑、删除、编辑完成按钮

    对每个按钮是否显示,使用v-show绑定变量,因为每一行的v-show绑定的变量必须是唯一的(不然的话操作此行,其他行的状态也会跟着变化),所以不可能提前在.ts中对变量进行初始化,只能使用本行的字段 ...

  7. Openstack web 添加和删除按钮

    注:当前已经时候用smaba将openstack环境的源码共享到windows系统上,并使用pycharm进行代码编辑和修改(参见openstack开发环境搭建).如下图:

  8. ABBYY FineReader 15 查看和编辑PDF

    使用ABBYY FineReader 15(Windows系统)OCR文字识别软件,用户可轻松查看和编辑各种类型的PDF数字文档,并可在文档中添加注释.添加与删除文字.格式化文字.搜索内容.保护PDF ...

  9. jquery easyui使用(四)······添加,编辑,删除

    前端: <div style="font-size: 25px; font-weight: 700; margin: 50px 0 10px 10px;"> 车辆登记 ...

随机推荐

  1. SHELL编程规范与变量

    shell相比标准开发语言比如JAVA,C,C++来说还是比较简单的,其实就是一堆命令的集合而已,初学者从简单的shell脚本学起,至于shell编程还是要有编程思想在里面,因此,循序渐进很重要,先研 ...

  2. python创建virtualenv虚拟环境

    pip install virtualenv virtualenv env_py36_crawl env_py36_crawl\Scripts\activate deactivate pip free ...

  3. Jenkins持续集成企业实战系列之Jenkins手动构建-----04

    注:原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.    最初接触Jenkins也是由于公司需求,根据公司需求Java代码项目升级的.(公司是 ...

  4. 5.js与jQuery入口函数执行时机

    js与jQuery入口函数执行时机区别: JS入口函数是在所有资源加载完成后,才执行.(包括:页面.外部js文件.外部css文件.图片) jQuery入口函数,是在文档加载完成后就执行.文档加载完成指 ...

  5. netstat查看tcp连接的状态

    netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}'

  6. hibernate自动生成时报错问题

    创建好了实体类和.hbm.xml文件,运行项目报上错: 实体类和xml文件中的字段要一致.(顺序和字段)

  7. mysql 导入 导出

    mysql导入导出sql文件   window下 1.导出整个数据库mysqldump -u 用户名 -p 数据库名 > 导出的文件名mysqldump -u dbuser -p dbname ...

  8. Docker镜像的导出和载入

    https://www.cnblogs.com/lishidefengchen/p/10564765.html

  9. Loj 6432. 「PKUSC2018」真实排名 (组合数)

    题面 Loj 题解 枚举每一个点 分两种情况 翻倍or不翻倍 \(1.\)如果这个点\(i\)翻倍, 要保持排名不变,哪些必须翻倍,哪些可以翻倍? 必须翻倍: \(a[i] \leq a[x] < ...

  10. python的下划线

    首先是单下划线开头,这个被常用于模块中,在一个模块中以单下划线开头的变量和函数被默认当作内部函数,如果使用 from a_module import * 导入时,这部分变量和函数不会被导入.不过值得注 ...