.display显示要设置的字段

1. 自定义样式类,显示出要显示的字段,在这个类中,也可以设置对应函数。 list_display=[check,"title",delete]
2.在 Modelxadmin中设置:list_display=["__str__"]
设置Modelxadmin的静态属性,即当注册的对象没使用样式类时,使用Modelxadmin的样式属性
3.处理表头
display中的函数名或者变量名作为表头
1.需要判断传的列表中的内容是函数名还是字符串
2.如果是字符串,判断是"__str__"还是其他的
3.让相应的字符串表头显示对应的中文,取到字段对象,引用字段中的verbose_name
4.处理表单数据
需要判断传的列表中的内容是函数名还是字符串
1.若是函数名,去执行对应的函数,取到对应的值
2.若是变量,利用反射到相应的数据中取到值
from Xadmin.service.Xadmin import site,Modelxadmin
from app01 import models
from django.utils.safestring import  mark_safe
class BookConfig(Modelxadmin):
    href=change/'%s/'自动在当前路径后拼接路径
    def edit(self, obj=None,  is_header=False):
        if is_header:  # 此时作表头处理
            return "操作"
        return mark_safe("<a href='change/%s/'>编辑</a>"%obj.pk)
    def delete(self, obj=None, is_header=False):
        if is_header:  # 此时作表头处理
            return "删除"
        return mark_safe("<a href='del/%s/'>删除</a>" % obj.pk)
    def check(self, obj=None, is_header=False):
        if is_header:  # 此时作表头处理
            return "选择"
        return mark_safe("<input type='checkbox'>")
    list_display=[check,"title","price","publish","authors",edit,delete]
site.register(models.Book,BookConfig)
View Code

3.显示设置

1.处理表头

处理表头 [check,'title', 'prcie',edit]
# 1.需要判断传的列表中的内容是函数名还是字符串
# 2.如果是字符串,判断是"__str__"还是其他的
 head=[]
        for field in self.list_display:
            if isinstance(field,str):
               if field=="__str__":
                   val=self.model._meta.model_name.upper()  #如果没定义样式类,表头就显示操作表的名字的大写
               else:
                   # class Book(models.Model):
                   #     title = models.CharField(max_length=32, verbose_name="书名")
                   #     price = models.DecimalField(max_digits=5, decimal_places=2, verbose_name="价格")
                   #如果是字段字符串,让表头显示其定义的中文表头。title是字段对象,找到title后title.verbose_name 获取这个属性值
                   obj=self.model._meta.get_field(field)
                   val=obj.verbose_name
            else:
                val = field(self,is_header=True)
            head.append(val)
View Code

2.处理表单数据

使用反射
        data_list=self.model.objects.all() #取出每一条数据的对象,data_list[0].字段名(title) 就能得到相应的数据
        content = []
        for obj in data_list:
            temp=[]
            for field in self.list_display:#自定义的样式类中有可能放的是自定义的函数名[check,'title', 'prcie',edit]
                #需要判断传的列表中的内容是函数名还是字符串
                if isinstance(field,str): #判断数据类型
                   val=getattr(obj,field)  #相当于obj.title,obj.price 其中obj.__str__会自动触发这个方法
                   print("结果是:",val)
                else:
                    val=field(self,obj,) #定义的方法,obj为这个方法执行的哪条数据对象
                temp.append(val)
            content.append(temp)
        return render(request,"list.html",{"content":content,"head":head,"type":type})
View Code

4.利用反向路由解析得到路径

'''
#Modelxadmin中设置
class Modelxadmin(object):
    list_display=["__str__"] #设置Modelxadmin的静态属性,即当注册的对象没使用样式类时,使用Modelxadmin的样式属性
    def __init__(self,model,site):  #如果传的是book,model就是Book 传的是publish,model就是Publiah
        self.model=model
        self.site=site
        self.model_name = self.model._meta.model_name #得到app名
        self.app_name = model._meta.app_label  #得到表名
        #为路由设置别名:
            def get_url_2(self):
        temp = []
        # print("=====",model_name )
        # temp.append(url(r"^$", self.list_view))
        temp.append(url(r"^$", self.list_view,name="{}/{}_list".format( self.app_name, self.model_name)))
        temp.append(url(r"^add/$", self.add_view,name="{}/{}_add".format( self.app_name, self.model_name)))
        # temp.append(url(r"^(\d+)/change/$", self.change_view,))
        temp.append(url(r"^change/(\d+)/$", self.change_view,name="{}/{}_change".format( self.app_name, self.model_name) ))
        temp.append(url(r"^del/(\d+)/$", self.del_view,name="{}/{}_del".format( self.app_name, self.model_name)))
        return temp
#自定以样式类中设置:
from django.utils.safestring import  mark_safe
from django.urls import reverse
class BookConfig(Modelxadmin):
    def edit(self, obj=None,  is_header=False):
        if is_header:  # 此时作表头处理
            return "操作"          #BookConfig中没有self.app_name,就去Modelxadmin找
        url_name="{}/{}_change".format( self.app_name, self.model_name)
        v = reverse(url_name, args=(obj.pk,))
        return mark_safe("<a href='%s'>编辑</a>" % v)
'''
View Code

显示页面的html

'''
<p>
    <span>序号</span>
    {% for foo in head %}
        <span>{{ foo }}</span>
    {% endfor %}
</p>

{% for foo in content %}
    <P>
      <span>{{ forloop.counter }}</span>
      {% for foo1 in foo %}
       <span>{{ foo1 }}</span>
    {% endfor %}
    </P>
{% endfor %}
'''

5.显示多对多的关系字段

多对多的字段,传过去之后在页面上显示字符串:app01.Author.None
例:作者是多对多的关系
 list_display=[check,"title","price","publish","authors",edit,delete]
 传过去之后在页面上显示字符串:app01.Author.None
解决方法一:将ManytoMany这个字段当作函数名传过去,不再写成字符串
在样式类中定义ManytoMany字段方法:
    def display_authors(self,obj=None, is_header=False):
        if is_header:
            return "作者名称"
        s=[]
        for author in obj.authors.all(): #必须使用all(),得到所有的作者对象
            s.append(author.name) #取出每个作者对象的name属性
        val=" | ".join(s)
        return mark_safe(val)

    list_display = [check, "title", "price", "publish", display_authors, edit, delete]
方法二:判断是不是ManytoMany类型
        data_list=self.model.objects.all() #取出每一条数据的对象,data_list[0].字段名(title) 就能得到相应的数据
        content = []
        for obj in data_list:
            temp=[]
            for field in self.list_display:#自定义的样式类中有可能放的是自定义的函数名[check,'title', 'prcie',edit]
                #需要判断传的列表中的内容是函数名还是字符串
                if isinstance(field,str): #判断数据类型
                    #处理多对多的字段方法二:判断是不是ManytoMany类型
                    from django.db.models.fields.related import ManyToManyField
                    many_obj = self.model._meta.get_field(field) #取到字段对象
                    if isinstance(many_obj,ManyToManyField):
                        t=[]
                        for i in getattr(obj,field).all():
                            t.append(i.name)
                        val=" | ".join(t)
                    else:val=getattr(obj,field)  #相当于obj.title,obj.price 其中obj.__str__会自动触发这个方法
list_display=[check,"title","price","publish","authors",edit,delete]
View Code

6.将删除,编辑,选择按钮封装起来

'''
app01.Xadmin 
1.使用继承:但是需要在每个样式类中设定
class Operation():
    def edit(self, obj,is_header):
        if is_header:  # 此时作表头处理
            return "操作"
        else:
            url_name = "{}/{}_change".format(self.app_name, self.model_name)  # BookConfig中没有self.app_name,就去Modelxadmin找
            v = reverse(url_name, args=(obj.pk,))
            return mark_safe("<a href='%s'>编辑</a>" % v)
    def delete(self, obj, is_header):
        if is_header:  # 此时作表头处理
            return "操作"
        return mark_safe("<a href='del/%s/'>删除</a>" % obj.pk)

    def check(self, obj, is_header):
        if is_header:  # 此时作表头处理
            return "选择"
        else:print(777)
        return mark_safe("<input type='checkbox'>")
class BookConfig(Modelxadmin, Operation):
    def check(self,obj=None, is_header=False):return super().check(obj, is_header)
    def edit(self,obj=None, is_header=False):return super().edit(obj, is_header)
    def delete(self,obj=None,  is_header=False):return super().delete(obj, is_header)
    list_display=[check,"title","price","publish","authors",edit,delete]
#如果不在BookConfig中定义check,edit,delete函数,在list_dispaly中加函数名后,会显示未定义。在用super调用时不能传位置参数
2.在Xadmin中设置,将check,edit,delete加到每个模型表的样式类中,模型表的样式类就不用再加这些函数
class Modelxadmin(object):
    # 选择按钮  编辑 删除
    def edit(self, obj=None, is_header=False):
        if is_header:  # 此时作表头处理
            return "操作"
        else:
            v=self.get_change_url(obj)
            return mark_safe("<a href='%s'>编辑</a>" %v)
    def delete(self, obj=None, is_header=False):
        if is_header:  # 此时作表头处理
            return "操作"
        v = self.get_del_url(obj)
        return mark_safe("<a href='%s'>删除</a>" %v)
    def check(self, obj=None, is_header=False):
        if is_header:  # 此时作表头处理
            return "选择"
        v = self.get_del_url(obj)
        return mark_safe("<input type='checkbox'>")
    #构建新的list_dispaly
    def new_list_display(self):
        temp=[]
        temp.append(Modelxadmin.check)
        temp.extend(self.list_display)
        temp.append(Modelxadmin.edit)
        temp.append(Modelxadmin.delete)
        return temp
    #处理表头 [check,'title', 'prcie',edit]
    for field in self.new_list_display():pass
     #处理表单数据,使用反射
      data_list=self.model.objects.all() #取出每一条数据的对象,data_list[0].字段名(title) 就能得到相应的数据
        content = []
        for obj in data_list:
            temp=[]
            for field in self.new_list_display():pass
样式类中直接传要显示的字段 list_display = ["title", "price", "publish", "authors"]
'''
View Code

7.设定样式类list_display_link

1.在循环表单数据时,如果list_display中的字段名在list_display_link,就将改字段的内容设置成编辑标签
2.如果表中数据设置成了编辑标签,那么编辑这个操作就没什么用了,应该判断如果样式中无list_display_link,就显示编辑操作,
有list_display_link则不显示编辑操作
在new_list_display中判断是否加编辑操作
    def new_list_display(self):
        temp=[]
        temp.append(Modelxadmin.check)
        temp.extend(self.list_display)
        #判断是否加编辑操作
        if not self.list_display_link:
            temp.append(Modelxadmin.edit)
        temp.append(Modelxadmin.delete)
        return temp
##将相应值设置成编辑标签
from django.db.models.fields.related import ManyToManyField
    try:
        many_obj = self.model._meta.get_field(field) #取到字段对象
        if isinstance(many_obj,ManyToManyField):
            t=[]
            for i in getattr(obj,field).all():
                t.append(i.name)
            val=" | ".join(t)
        else:
            #判断改字段是否在list_display_link,如果在,就设置成标签形式,不再就正常显示
            if field in self.list_display_link:
                edit_url=self.get_change_url(obj)
                val=mark_safe("<a href='%s'>%s</a>"%(edit_url,getattr(obj,field)))
            else:val=getattr(obj,field)
    except Exception as e:
        val = getattr(obj, field)
View Code
显示页面的函数形式
'''
 def list_view(self, request): #self是Modelxadmin的实例对象,要么是自定义样式类的实例对象
    # print("这里是:", model_name )
    type=request.GET.get("name")
    if not type:type=""
    print(type)
    print(self.model)  #用户调用的哪张表,self.model就是哪张表  <class 'app02.models.Order'>
    print("新的是:",self.new_list_display())
    #处理表头 [check,'title', 'prcie',edit]
    # 1.需要判断传的列表中的内容是函数名还是字符串
    # 2.如果是字符串,判断是"__str__"还是其他的
    head=[]
    # for field in self.list_display:
    for field in self.new_list_display():
        if isinstance(field,str):
           if field=="__str__":
               print("食物")
               val=self.model._meta.model_name.upper()  #如果没定义样式类,表头就显示操作表的名字的大写
           else:
               # class Book(models.Model):
               #     title = models.CharField(max_length=32, verbose_name="书名")
               #     price = models.DecimalField(max_digits=5, decimal_places=2, verbose_name="价格")
               #如果是字段字符串,让表头显示其定义的中文表头。title是字段对象,找到title后title.verbose_name 获取这个属性值
               obj=self.model._meta.get_field(field)
               val=obj.verbose_name
        else:
            val = field(self,is_header=True)
        head.append(val)
        print(head)
    #处理表单数据,使用反射
    data_list=self.model.objects.all() #取出每一条数据的对象,data_list[0].字段名(title) 就能得到相应的数据
    content = []
    for obj in data_list:
        temp=[]
        # for field in self.list_display:#自定义的样式类中有可能放的是自定义的函数名[check,'title', 'prcie',edit]
        for field in self.new_list_display():
            #需要判断传的列表中的内容是函数名还是字符串
            if isinstance(field,str): #判断数据类型
                #处理多对多的字段方法二:判断是不是ManytoMany类型
                from django.db.models.fields.related import ManyToManyField
                try:
                    #如果是__str__ 走到这会报错,因此使用抛出异常处理
                    many_obj = self.model._meta.get_field(field) #取到字段对象
                    if isinstance(many_obj,ManyToManyField):
                        t=[]
                        for i in getattr(obj,field).all():
                            t.append(i.name)
                        val=" | ".join(t)
                    else:
                        # val=getattr(obj,field)  #相当于obj.title,obj.price 其中obj.__str__会自动触发这个方法
                        #判断改字段是否在list_display_link,如果在,就设置成标签形式,不再就正常显示
                        if field in self.list_display_link:
                            edit_url=self.get_change_url(obj)
                            val=mark_safe("<a href='%s'>%s</a>"%(edit_url,getattr(obj,field)))
                        else:val=getattr(obj,field)
                except Exception as e:
                    val = getattr(obj, field)
                print("结果是:",val)
            else:
                val=field(self,obj,) #定义的方法,obj为这个方法执行的哪条数据对象
            temp.append(val)
            print("temp是:", temp)
        content.append(temp)
    print("content是:", content)
    # ##获取增加页面的url 点击增加的时候,跳到增加页面。自动拼接
    # add_url="add"
    return render(request,"list.html",{"content":content,"head":head,"type":type,"add_url":self.get_add_url()})



'''
View Code

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-09-22
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-11-02
猜你喜欢
  • 2022-01-08
  • 2022-12-23
  • 2021-06-21
  • 2022-03-06
  • 2022-12-23
  • 2021-04-18
相关资源
相似解决方案