django中的admin組件之自定義組件的數據展示以及自定義列


雖然我們基本實現了我們自定義組件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_name
app_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)

 

那么在視圖函數中怎么用呢?

 

 

 

 

上面涉及到的知識點:

知識點一:._meta.get_field(field)

 知識點二:mark_safe

如果要往頁面中返回標簽的話,django會有這樣一個機制,它會將尖角號進行轉譯,所以渲染在頁面后就會出錯,引入from django.utils.safestring import mark_safe,使用mark_safe是告訴django不要對我們的標簽轉譯,它的作用和頁面中使用的safe的作用一樣的。

 

































免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM