开发stark组件2

上个博客我们,我们写到了要告诉前端页面应该展示什么字段 ,今天我们就来详细说一下 如何后端取到我们需要的字段 并在前端页面展示出来

首先我们先把前端页面写死,先看一下效果

后端查看页面代码:

    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

原文地址:https://www.cnblogs.com/yftzw/p/9357582.html