上個博客咱們,咱們寫到了要告訴前端頁面應該展現什麼字段 ,今天咱們就來詳細說一下 如何後端取到咱們須要的字段 並在前端頁面展現出來css
首先咱們先把前端頁面寫死,先看一下效果html
後端查看頁面代碼:前端
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})
前端頁面:jquery
<!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>
顯示的效果數據庫
這就咱們今天要完成的 根據自定義配置的不一樣 顯示不一樣的字段bootstrap
既然咱們要根據自定義的字段 顯示相應的字段 咱們就須要在後端 取到相應的字段 後端
下面咱們就改爲從數據庫裏取值安全
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})
上面只是拿到了表格的內容 表格的列名尚未取到app
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