上个博客我们,我们写到了要告诉前端页面应该展示什么字段 ,今天我们就来详细说一下 如何后端取到我们需要的字段 并在前端页面展示出来
首先我们先把前端页面写死,先看一下效果
后端查看页面代码:
def list_view(self,request): #用户访问的模型表: self.model print("self.model:",self.model) print("self.list_display",self.list_display,'-'*30) queryset=self.model.objects.all() list_name=[ '书名', '价格' ] data_list=[ ['金梅',122], ['火影忍者',23], ['乡间小道',8], ] return render(request,"stark/list_view.html",{'data_list':data_list,'list_name':list_name})
前端页面:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css"> </head> <body> <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <table class="table table-bordered "> <thead> <tr> {% for foo in list_name %} <th>{{ foo }}</th> {% endfor %} </tr> </thead> <tbody> {% for foo in data_list %} <tr> {% for bar in foo %} <td>{{ bar }}</td> {% endfor %} </tr> {% endfor %} </tbody> </table> </div> </div> </div> <script src="/static/jquery-3.3.1.min.js"></script> </body> </html>
显示的效果
这就我们今天要完成的 根据自定义配置的不同 显示不同的字段
既然我们要根据自定义的字段 显示相应的字段 我们就需要在后端 取到相应的字段
下面我们就改成从数据库里取值
def list_view(self,request): queryset=self.model.objects.all() data_list=[] for obj in queryset: temp=[] for ziduan in self.list_display: val=getattr(obj,ziduan) temp.append(val) data_list.append(temp) print(temp) print(data_list,'........') return render(request,"stark/list_view.html",{'data_list':data_list})
上面只是拿到了表格的内容 表格的列名还没有取到
def list_view(self,request): queryset=self.model.objects.all() header_list=[] for name in self.list_display: obj = self.model._meta.get_field(name)#根据字段找到相应的对象 val = obj.verbose_name#拿到字段的中文名 header_list.append(val) data_list=[] for obj in queryset: temp=[] for ziduan in self.list_display: val=getattr(obj,ziduan) temp.append(val) data_list.append(temp) print(temp) print(data_list,'........') return render(request,"stark/list_view.html",{'data_list':data_list,'header_list':header_list})
这样我们就完成了 从数据库里取值 但是还有一个问题 我们取到的list_display是配置类默认的 而非我们自定义的 就会报错 所以我们需要加个判断
header_list=[] for name in self.list_display: if name=='__str__': val = self.model._meta.model_name.upper() print(val,'1') else: obj = self.model._meta.get_field(name)#根据字段找到相应的对象 val = obj.verbose_name#拿到字段的中文名 header_list.append(val)
上面已经完成了最初的目标 但是我们也可以在此基础上添加自定义列 如下图
app01下的stark 自定义一个删除列
def delete_col(self, obj=None, is_header=False): if is_header: return "删除" return mark_safe("<a href='%s/delete/'>删除</a>" % obj.pk) #mark_safe相当于标签是安全的 不要转译 list_display = ["title","price",delete_col] site.register(models.Book,BookConfig)
这样我们list_display就会有一个非字符串的值
那在我们的配置类就需要判断一个是否,否则程序就会崩掉了
class ModelStark(): def __init__(self,model): self.model = model list_display = ["__str__"] def list_view(self,request): #用户访问的模型表: self.model print("self.model:",self.model) # print("self.list_display",self.list_display,'-'*30) queryset=self.model.objects.all() header_list=[] for name in self.list_display: if isinstance(name,str): if name=='__str__': val = self.model._meta.model_name.upper() print(val,'1') else: obj = self.model._meta.get_field(name)#根据字段找到相应的对象 val = obj.verbose_name#拿到字段的中文名 else: val=name(self,is_header=True) header_list.append(val) data_list=[] for obj in queryset: temp=[] for ziduan in self.list_display: if isinstance(ziduan,str):#判断是不是字符串 val=getattr(obj,ziduan) else: val=ziduan(self,obj) temp.append(val) data_list.append(temp) print(temp) print(data_list,'........') return render(request,"stark/list_view.html",{'data_list':data_list,'header_list':header_list})
但是这样还不够好 我们应该把删除这种操作设计成默认的 我们知道设置成默认的就是在配置类里添加,但是有一个问题 如果将这些加入list_display里,那如果有自定义的 那么配置类就会被覆盖 所以我们要想一个办法解决这个问题
先将删除 编辑 选择 定义到配置类
def delete_col(self,obj=None,is_header=False): if is_header: return "删除" return mark_safe("<a href='%s/delete/'>删除</a>"%obj.pk) def edit_col(self,obj=None,is_header=False): if is_header: return "编辑" return mark_safe("<a href=''>编辑</a>") def check_col(self,obj=None,is_header=False): if is_header: return "选择" return mark_safe("<input type='checkbox'>")
既然我们把上面的函数放进list_display里 也会被自定义的类覆盖 那我们可以在创建新列表 把上面的和list_display全部放进去返回 不就可以了
def get_new_list_display(self): new_list_display=[] new_list_display.extend(self.list_display) new_list_display.append(ModelStark.edit_col) new_list_display.append(ModelStark.delete_col) new_list_display.insert(0,ModelStark.check_col) return new_list_display