虽然我们基本实现了我们自定义组件stark的功能,接下来就是显示数据了。
今天我们先来写查。先来写表单部分
我们如果需要显示我们自己配置类中的字段,应该怎么做呢?
我们有这样一个想法,将这些数据放在一个列表中,类似这样[[‘python’,122],[‘linux’,110]],然后在页面上依次循环这个列表,取值就行了。
self.model.objects.all()中里面有我们需要的对象,self.list_display中有我们需要的字段。所以:
def listview(self,request): # print(self)# 当前访问摩星表的配置类对象 # print(self.model)# 当前访问的模型表 data_list = self.model.objects.all() # 取到所有的对象 [‘python‘,‘linux‘]# 构建数据表单部分 new_data_list = [] for obj in data_list: temp = [] for field in self.list_display: # [‘price‘,‘title‘] val = getattr(obj,field) # getattr通过字符串取值 temp.append(val) # [‘python‘,‘100‘] [‘linux‘,‘120‘] new_data_list.append(temp) # [[‘python‘,‘100‘],[‘linux‘,‘120‘]] return render(request,‘list.html‘,locals())
在页面上我们这样获取数据:
<table class="table table-hover"> <thead> <tr></tr> </thead> <tody> {% for data in new_data_list %} <tr> {% for item in data %} <td>{{ item }}</td> {% endfor %} </tr> {% endfor %} </tody> </table>
但是这里面有一个bug,因为我们是以book为例 的,book是我们自己写的配置类,所以list_display中有我们写的字段,但是当我们访问publish的时候,publish用的是默认的配置类,list_display里面是没有字段的,所以在 for field in self.list_display: # [‘price‘,‘title‘] 这一步出错。所以我们应该在最前面定义一个list_display = [‘__str__‘],如果使用的是默认的配置类,就让他执行__str__方法。
我们都知道,在admin组件中,我们自己定义的配置类中,list_display中是可以放一对多字段,但是不能放多对多字段,,所以在我们写的自定义组件中,也同样不能放多对多字段,那我们就像显示多对多的字段,该怎么做呢?
这里先说一个知识点:我们之前介绍过在我们自己写的组件中,
model_name = self.model._meta.model_nameapp_label = self.model._meta.app_label这两种方法可以获得当前表的名字和当前app的名字。在介绍一种field_obj = self.model._meta.get_field(field)这种方法能够取到表中具体的某一字段对象。所以我们想要放多对多字段之前,先进行判断,
def listview(self,request): # print(self)# 当前访问摩星表的配置类对象 # print(self.model)# 当前访问的模型表 data_list = self.model.objects.all() # 构建数据表单部分 new_data_list = [] for obj in data_list: temp = [] for field in self.list_display: from django.db.models.fields.related import ManyToManyField field_obj = self.model._meta.get_field(field) # 获取表中某个字段 if isinstance(field_obj,ManyToManyField): # 判断field_obj字段是否属于多对多字段 many_data_list = getattr(obj, field).all() # 如果是多对多字段,book.author.all()取到所有作者对象 item = [str(item) for item in many_data_list] val = ‘,‘.join(item) else:# 如果不是多对多字段,获取值 val = getattr(obj,field) temp.append(val) new_data_list.append(temp) return render(request,‘list.html‘,locals())
这样就行了。这样表单中的数据就处理完了。接下来我们来写表头部分。
我们想表头部分不就是在list_display中吗?直接在页面中循环不就行了吗。这样固然没错,但是这样渲染出来的表头是英文的,我们想要中文的怎么做?
def listview(self,request): # print(self)# 当前访问摩星表的配置类对象 # print(self.model)# 当前访问的模型表 data_list = self.model.objects.all() # 构建表头部分 header_list=[] for field in self.list_display: # 循环每一个字段,if field == ‘__str__‘: # 判断field是__str__,说明使用的是默认配置类,将表头就定为表的名字 val = self.model._meta.model_name else: # 否则说明使用的自定义配置类, obj = self.model._meta.get_field(field) # 得到自定义配置类的字段对象, val = obj.verbose_name # 获取字段的verbose_name,verbose_name是models中每一个字段的可设置的参数 header_list.append(val)
# 构建数据表单部分 new_data_list = [] for obj in data_list: temp = [] for field in self.list_display: from django.db.models.fields.related import ManyToManyField field_obj = self.model._meta.get_field(field) # 获取表中某个字段 if isinstance(field_obj,ManyToManyField): # 判断field_obj字段是否属于多对多字段 many_data_list = getattr(obj, field).all() # 如果是多对多字段,book.author.all()取到所有作者对象 item = [str(item) for item in many_data_list] val = ‘,‘.join(item) else:# 如果不是多对多字段,获取值 val = getattr(obj,field) temp.append(val) new_data_list.append(temp)
return render(request,‘list.html‘,locals())
在页面中,
<table class="table table-hover"> <thead> <tr> {% for header in header_list %} <th>{{ header }}</th> {% endfor %} </tr> </thead> <tody> {% for data in new_data_list %} <tr> {% for item in data %} <td>{{ item }}</td> {% endfor %} </tr> {% endfor %} </tody> </table>
这样表头就完了。
接下来我们写自定义列
我们在查看书籍的时候肯定够编辑和删除对不对,所以我们要在表头加一列:操作。这该怎么做,
添加操作当然要在自定义配置类中的list_display中添加操作,list_display = ["title", "price", "publish",‘authors‘,edit,delete]:
# 定义自己的配置类 class Bookconfig(sites.ModelAdmin): def edit(self,obj=None,is_header=False): if is_header: return ‘操作‘ else: return mark_safe("<a href=‘/stark/app01/book/%s/change/‘>编辑</a>"%obj.pk) def delete(self,obj=None,is_header=False): if is_header: return ‘操作‘ else: return mark_safe("<a href=‘/stark/app01/book/%s/delete/‘>删除</a>" % obj.pk) # list_display‘ must not be a ManyToManyField. list_display = ["title", "price", "publish",‘authors‘,edit,delete] sites.site.register(models.Book,Bookconfig)
那么在视图函数中怎么用呢?
上面涉及到的知识点:
原文地址:https://www.cnblogs.com/yb635238477/p/9557718.html