zoukankan      html  css  js  c++  java
  • Xadmin

    一  启动

    1.创建一个Xadmin的app

    2.在每个APP中创建Xadmin.py文件

    3.在Xadmin中找到apps.py,如下图:

            

              下面的框中内容代表,加载项目时,自动运行整个项目中所有Xadmin.py

    二 注册

    1.把Xadmin当做组件可以拿到别的应用去用,所以把源码写到Xadmin的app中

      在Xadmin中创建一个service包,包中创建一个Xadmin.py

    class ModelXadmin():
        def __init__(self,model,site):
            self.model = model
            self.site = site
    
    
    class XadminSite(object):
        def __init__(self, name='admin'):
            self._registry = {}
        def register(self, model, admin_class=None, **options):
                if not admin_class:  #如果注册时不用自定义样式类,默认用ModelXadmin
                         admin_class = ModelXadmin
                self._registry[model] = admin_class(model, self)#用自己定制的样式类
    
                
    site=XadminSite() #实例化一个单例对象site 
                      #每次注册都不会重新加载,都会存入_registry的字典中

    可以在其他APP中的Xadmin中引入单例对象 进行注册:

    from Xadmin.service.Xadmin import site,ModelXadmin
        from app01.models import *  #引用app01下的 数据表
        site.register(表名)
        site.register(Book)
        site.register(Auth)

    三 url分发

    把所有构建url分发的函数 封装在ModelXadmin类中,在urls.py中就可以用url(r'^Xadmin/', site.urls)

    from django.conf.urls import url
    from django.shortcuts import HttpResponse,render,redirect
    class ModelXadmin(object):
        def __init__(self,model,site):
    
            self.model=model
            self.site=site
    
        def list_view(self, request):
            print("self.model",self.model)
    
            data_list=self.model.objects.all()
            print("data_list",data_list)
            return render(request, 'list_view.html',{"data_list":data_list})
    
        def add_view(self, request):
            return render(request, 'add_view.html')
    
        def change_view(self, request, id):
            return render(request, 'change_view.html')
    
        def delete_view(self, request, id):
            return render(request, 'delete_view.html')
    
        def get_urls2(self):
            temp = []
    
            temp.append(url(r"^$", self.list_view))
            temp.append(url(r"^add/$", self.add_view))
            temp.append(url(r"^(d+)/change/$", self.change_view))
            temp.append(url(r"^(d+)/delete/$", self.delete_view))
    
            return temp
    
        @property
        def urls2(self):
            return self.get_urls2(), None, None
    
    
    class XadminSite(object):
        def __init__(self, name='admin'):
            self._registry = {}
    
    
        def get_urls(self):
    
            print(self._registry)  # {Book:modelAdmin(Book),.......}
    
            temp = []
            for model, admin_class_obj in self._registry.items():
                app_name = model._meta.app_label
                model_name = model._meta.model_name
    
                temp.append(url(r'^{0}/{1}/'.format(app_name, model_name), admin_class_obj.urls2), )
            return temp
    
        @property
        def urls(self):
    
            return self.get_urls(),None,None
    
        def register(self, model, admin_class=None, **options):
            if not admin_class:
                     admin_class = ModelXadmin
    
            self._registry[model] = admin_class(model, self) # {Book:ModelAdmin(Book),Publish:ModelAdmin(Publish)}
    
    site=XadminSite()
    server/Xadmin.py

    如何在不同url的相同视图函数中,展示不同的数据

    1  先创建增删改查的html文件,在视图中renderhtml页面

    2  注册的时候如果不传自己的样式,所有模型表都默认 用的admim_class样式类 

      把二级分发以及对应的增删改查视图函数,从XadminSite中拿到ModelXadmin(配置类)类中

      for model , admin_class_obj in self._registry.items()  中   admin_class_obj 就是ModelXadmin的实例对象,

      在XadminSite中拿二级分发就可以 admin_class_obj.urls2,这样就多了一个self.model   

      访问哪张表,self.model就是哪张表模型,就能拿到对应表的数据,实现相同的模板,渲染不同数据

      在视图函数中拿到当前表数据(如图):

      

     五  增删改查的 页面设计

    额外知识点:

    在后端把标签传给前端,前端会做转义,变成字符串的形式,无法渲染页面,需要用:

    from django.utils.safestring import  mark_safe
    mark_safe("<a href=''>编辑</a>")

    由于不知道要渲染的数据是谁,所以不能 向之前一样,在模板里渲染

    1     需要把数据做成列表套列表的形式:[["title",price],["python红宝书",23],["python宝典",38]]

      需要在后端循环当前访问的表(self.model.objects.all())

      先在app下的Xadmin中注册的时候,把想展示的字段数据放在list_display 中:list_display=["nid","title","publish"],然后在ModelXadmin中创建一个list_display=[]

      如果注册的时候,没有自定义样式类,list_display会为空,所以想要默认显示,需要在ModelXadmin中让list_display=[__str__]

    def list_view(self, request)中的代码(要展示的数据):


      data_list = self.model.objects.all() #当前访问的页面所有数据 new_data_list=[] for obj in data_list: # data_list [book_obj,book_obj2,...] temp=[] for field in self.list_display: # ['title', 'prcie'] 注册时列表中添加所要展示的字段,如果想在列表添加函数,需要注册时,自定义样式类时,在类中写函数 if isinstance(field,str): #list_display中可能存放函数,所以需要先判断一下 val=getattr(obj,field) #拿到的field是字符串,所以需要用getattr代替obj.field(对象.属性) else: val=field(self,obj) #拿到的是函数(函数中可以返回a标签,编辑,删除),拿到返回值 temp.append(val) #把函数的返回值或者标的字段添加到temp中 new_data_list.append(temp) #把temp列表 放在 new_data_list列表中,做成列表套列表的形式

    def list_view(self, request)中的代码(要展示的表头):

    返回的一个列表就可以了,虽然list_display存的是每一个字段名,可以循环出来作为表头,但是这样无法修改成中文字段,所以,在创建表字段加一个verbose_name属性:

    class Book(models.Model):
    
        nid = models.AutoField(primary_key=True,verbose_name=" 编号")
        title = models.CharField( max_length=32,verbose_name="书籍名称")
        publishDate=models.DateField()
        price=models.DecimalField(max_digits=5,decimal_places=2)

    如何显示中文:

      创建表 中的每一个字段,其实都是一个实例对象,拿到当前字段的实例对象用:

      

      obj= 表名._meta.get_filed(字段)

      然后:    obj.verbose_name   就可以拿到中文名

    # 处理表头
            #header_list=["ID","书籍名称","出版社"]
            header_list=[]
            for field in self.list_display: # [check,"nid","title","publish",edit,delete]
                if isinstance(field,str):
                    if field=="__str__":                   #如果是字符串,证明没有自定义样式类
                        val= self.model._meta.model_name.upper()   #当前表名大写作为字段
                    else:                                  
                        field_obj=self.model._meta.get_field(field)
                        val=field_obj.verbose_name
    
                else:
                    val=field(self,is_header=True)  #  获取表头,传is_header=True 证明拿到的是表头,不需要写修改 删除
    
                header_list.append(val)

    当前查看表:

    编辑和删除都是空的,那么,如何点击编辑删除,跳转到当前数据的指定页面:

    1  在视图中,执行列表中的函数时,把obj,传进去:

     else:
                        val=field(self,obj)     #拿到的是函数(函数中可以返回a标签,编辑,删除),拿到返回值

    2  自定义样式类就可以拿到当前对象,拼接url:

    class BookConfig(ModelXadmin):
        def edit(self,obj=None,is_header=False):   #obj=None  调用时,可传可不传。is_header=False,如果传了,证明是表头,不传走下面,返回编辑的a标签
            if is_header:
                return "操作"
            # 反向解析:url
            return mark_safe("<a href='%s/change/'>编辑</a>"%obj.pk)

      上面这种方式就可以拼接成想要的url,该方法不好,下面用反向解析找到url:

        定义视图函数的每一个url路径的时候,起一个name别名

  • 相关阅读:
    2018杭州初雪
    李宗盛
    张爱玲(句子迷)
    RFBnet论文笔记
    AXI总线简介、ID分析、DMA、Vivado烧录、系统集成
    axi总线之零:概述
    怎么理解 Redis 事务?
    Redis 集群最大节点个数是多少?
    怎么测试 Redis 的连通性?
    Redis 集群如何选择数据库?
  • 原文地址:https://www.cnblogs.com/pygg/p/9146906.html
Copyright © 2011-2022 走看看