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)

那么在视图函数中怎么用呢?

 

上面涉及到的知识点:
































猜你喜欢

转载自www.cnblogs.com/yb635238477/p/9557718.html