zoukankan      html  css  js  c++  java
  • 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的作用一样的。
































  • 相关阅读:
    dropdownList级联刷新gridView
    Jquery解析json数据
    ASP.NET UserControl 通信
    sharepointWebPart开发、部署、发布过程全记录
    buffer和cache怎么让你们解释的那么难理解?
    Global.asax用法分析
    1、什么是ASP.NET MVC
    在Global.asax文件里实现通用防SQL注入漏洞程序
    ABP vNext V5 + VS2022+ .Net 6.0 学习笔记(1)
    使用IIS时的小问题
  • 原文地址:https://www.cnblogs.com/yb635238477/p/9557718.html
Copyright © 2011-2022 走看看