stark——查看页面编辑删除按钮
一、数据列表
设计查页面,主要展示两部分内容,表头部分和数据部分, 表头通过遍历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——查看页面编辑删除按钮的更多相关文章
- selenium依次点击页面的删除按钮
需要依次点击页面的删除按钮,如下图: @Test public static void FaBu() { TestMenuJump.jumpExam(driver); TestMenuJump.jum ...
- [App Store Connect帮助]二、 添加、编辑和删除用户(2)查看并编辑您的个人帐户
您可以在 App Store Connect 的“编辑个人资料”中查看和编辑个人信息.如果您的 Apple ID 与多个帐户相关联,您可以在您的用户帐户之间切换. 查看您的个人帐户 在任意 App S ...
- ajax 实现加载页面、删除、查看详细信息,以及bootstrap网页的美化
由于有些的程序员可能不是很会Photoshop,所以为了美化页面,我们可以借助工具bootstrap,实现起来相对就要比之前做的美观一些, 今天我用bootstrap把之前做的显示表格进行了一下美 ...
- GridView中的编辑和删除按钮,执行更新和删除代码之前的更新提示或删除提示
在GridView中,可以通过设计界面GridViewr任务->编辑列->CommandField,很简单的添加的编辑和删除按钮 在前台源码中,可以看到GridView自动生成了两个列. ...
- 【HTML5】页面点击按钮添加一行 删除一行 全选 反选 全不选
页面点击按钮添加一行 删除一行 全选 反选 全不选 页面效果图如下 html页面代码 <!DOCTYPE html> <html> <head> & ...
- el-table中操作一栏怎么根据当前行的信息显示编辑、删除、编辑完成按钮
对每个按钮是否显示,使用v-show绑定变量,因为每一行的v-show绑定的变量必须是唯一的(不然的话操作此行,其他行的状态也会跟着变化),所以不可能提前在.ts中对变量进行初始化,只能使用本行的字段 ...
- Openstack web 添加和删除按钮
注:当前已经时候用smaba将openstack环境的源码共享到windows系统上,并使用pycharm进行代码编辑和修改(参见openstack开发环境搭建).如下图:
- ABBYY FineReader 15 查看和编辑PDF
使用ABBYY FineReader 15(Windows系统)OCR文字识别软件,用户可轻松查看和编辑各种类型的PDF数字文档,并可在文档中添加注释.添加与删除文字.格式化文字.搜索内容.保护PDF ...
- jquery easyui使用(四)······添加,编辑,删除
前端: <div style="font-size: 25px; font-weight: 700; margin: 50px 0 10px 10px;"> 车辆登记 ...
随机推荐
- 华为敏捷DevOps实践:产品经理如何开好敏捷回顾会议
大家好,我是华为云DevCloud项目管理服务的产品经理 恒少:) 作为布道师和产品经理,出差各地接触客户是常态,经常和华为云的客户交流.布道.技术沙龙,但是线下交流,覆盖的用户总还是少数.我希望借助 ...
- C++20草案中的宇宙飞船运算符(<=>,spaceship operator)
C++20草案中的宇宙飞船运算符(<=>,spaceship operator) Herb Sutter提议的新三路运算符<=>已经被合入C++20草案中. 宇宙飞船运算符(h ...
- JsonToHtml
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 使用带参数的SQL语句向数据库中插入空值
private void button1_Click(object sender, EventArgs e) { string name = textBox1.Text; int age = Conv ...
- 2.2、Softmax Regression算法实践
Softmax Regression算法实践 有了上篇博客的理论知识,我们可以利用实现好的函数,来构建Softmax Regression分类器,在训练分类器的过程中,我们使用多分类数据作为训练数据: ...
- SprimgMVC学习笔记(十一)—— 解决静态资源无法被springmvc处理
方法一:在springmvc.xml中配置 <!-- 解决静态资源无法被springMVC处理的问题 --> <mvc:default-servlet-handler /> 方 ...
- Android 应用资源及R文件的位置
1.介绍 (1)常识 (2)在res目录下新建资源文件(例如数字资源) app--->res,选择res,右击new--->value resource file 2.字符资源(strin ...
- wzoi(栈模拟)
链接:https://ac.nowcoder.com/acm/contest/332/I 来源:牛客网 题目描述 bleaves 最近在 wzoi 上面做题. wzoi 的题目有两种,一种是 noip ...
- HibernateUtil hibernate4.0以上
package com.test.bbs.util; import org.hibernate.Session; import org.hibernate.SessionFactory; import ...
- golang flag
本文主要对golang环境下命令行的解析进行了相关的总结.命令行在C下有getopt等函数, 在golang下提供了更为方便的处理方法. 1.命令行参数获取:命令行获得可通过os.Args参数, Ar ...