zoukankan      html  css  js  c++  java
  • xadmin系列之启动、注册、分发

    a、启动首先要加载settings中定义的INSTALLED_APPS列表中的app

    b、我们进入xadmin的XadminConfig文件

    from django.apps import AppConfig
    from django.utils.module_loading import autodiscover_modules
    
    class XadminConfig(AppConfig):
        name = 'xadmin'
    
    
        # django加载这个app,就会自动执行ready这个方法
        def ready(self):
            # 扫描所有的xadmin.py文件,并执行
            autodiscover_modules("xadmin")
    

      

    这个文件就需要扫描所有app下的xadmin文件,并执行,因为我们这里是重写admin,所以这里的是xadmin,在djangon中,这里是admin

    c、我们在看每个app下的xadmin文件,通过看代码,我们可以知道,每个xadmin文件的作用就是注册这个app的model,这里xadmin,我们先简单的实现,仅仅传递一个model对象进行,后面这里我们更新这张表

    from django.contrib import admin
    from xadmin.services.xadmin import site
    from app2 import models
    # Register your models here.
    
    
    site.register(models.app2Dept)
    site.register(models.app2Person)
    site.register(models.app2testorm)
    
    # print(site._register)
    

      

    这里导入site,这个就是我们前面讲的那个单实例对象

    c、这里我们在看下site这个实例的ergister方法

    register这个方法需要可以传递2个参数进去,其中model就是我们前面传递的model的对象,admin_class这个我们传递了一个默认参数进去,如果在调用site.register方法没有传递admin_class这个值,那么

    我们就需要这个为admin_class给一个默认值,这里大家一定还不知道admin_class到底要要放什么数据,这里存放的某张表中的l下面的这些信息,比如要显示什么字段,排序、搜索、过滤这些信息

    到了这里,我们可以看到self._register这个字典的k值是表的对象,v值是这个表的admin_class对象,上面的例子我们是没有为admin_class传递值,他默认是xadmin_class这个类,然后我们实例化这个类

    然后做为self._register这字典的v值传递进去

    至此简单的注册已经完成,复杂的注册,比如传递admin_class和xadmin_class这个类的代码我们后面在讲解

    d、下面看下分发,我们要设计一个这样的url,我们要用一个url实现对每张表的增删改查,这里就需要用到前面讲的路由分发

    先看下一级分发

    from django.conf.urls import url
    from django.contrib import admin
    
    
    from xadmin.services import xadmin
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^xadmin/', xadmin.site.urls),
    ]
    

      

    这里导入了xadmin.site.urls方法,下面我们看下这个方法

    e、这里看下urls文件中的代码,urls方法也是在xadminsite这个类中定义的,这里加了property这个装饰器,这个装饰器会把一个方法变成属性,不加括号就可以直接调用,所以我们在回头看下路由分发中,调用urls这个方法没有加括号,因为我们已经把方法变成属性了,在我们其他的django项目中,这里都是写一个函数的名称,且没有带括号,所以他们不会直接执行,这里就会直接执行,不能方法

     f、urls方法调用了self.get_urls方法,我们在看下self.get_urls的方法,通过self._register这个字典中的表对象,获取这个表对应的app的名称和表的名称,然后拼接url,这里我们要注意到,他还做了三级分发,这一级只到了/app名称/表的名称/这一级,第三级,我们就到对这个表做增删改查的操作

     g、下面我们在看下geturlsopertion这个方法,这里我们注意到的,这个方法是类admin_class这个类的方法,因为我们在前面的注册操作,为self._register字典的v值就是xadmin_class的对象

     h、然后在xadmin_class这个类中定义了增删改查的函数

     至此,我们的整个流程就走通了

    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    下面我们说一下注册我们是怎么做的,我们主要说一下查看这个url对应的各种操作

    class myapp1person(xadmin_class):
        def edit(self,obj=None,is_head=False):
            if not is_head:
            # return mark_safe("""<a href="/xadmin/app1/app1person/{pid}/change">编辑</a>""".format(pid = obj.pid))
    
                return mark_safe("""<a href="{pid}/change">编辑</a>""".format(pid=obj.pid))
            else:
                return "编辑操作"
    
        def delete(self,obj=None,is_head=False):
            if not is_head:
                return mark_safe("""<a href="#">删除</a>""")
            else:
                return "删除操作"
        def check(self,obj=None,is_head=False):
            if not is_head:
                return mark_safe("""<input type="checkbox">""")
            else:
                return "check"
        list_display = [check,"name","salary",edit,delete,"dept","pid",]
    
    site.register(models.app1Dept)
    site.register(models.app1Person,admin_class=myapp1person)
    

      

     如何实现自定义的字段,这里我们定义了一个函数,这个放一个函数的名称就可以了,下面我们讲一下函数

     如果是要获取表头信息,则不走返回表的内容的信息,而是直接返回表头的字符串,这里obj为什么给一个默认值为None,如果如果是获取表头信息,是不需要obj,如果是表的身体的内容的值,才需要

    最后我们在看下xadmin_admin这个类

    class xadmin_class(object):
        list_display = ["__str__"]
        def __init__(self,model,site):
            self.model = model
            self.site = site
    
        def list_view(self,request):
            print(self.list_display)
            print("="*120)
            # models.app1testorm.objects.all().values_list()
    
            # if self.list_display:
            #     # 方式1,根据list_display获取指定字段数据
            #     # data = self.model.objects.all().values_list(*self.list_display)
            #     # print(data)
            #
            #     # 方式2:利用反射,去获取,然后自己组建列表返回给前端
            #     obj = getattr(self.model.objects.all()[0],self.list_display[0])
            #     print(obj)
            # else:
            #     list_display = ["object",]
            #     data = []
            #     obj_list = self.model.objects.all()
            #     for o in obj_list:
            #         temp = [o,]
            #         data.append(temp)
            data = []
            head_list = []
            flag = False
            for m in self.model.objects.all():
                temp = []
                for i in self.list_display:
                    if isinstance(i,str):
                        f = getattr(m,i)
    
                    else:
                        f = i(self.model,m)
    
                    temp.append(f)
                data.append(temp)
    
            # print(self.list_display)
            if not flag:
                for h in self.list_display:
    
                    if isinstance(h,str):
                        print(h)
                        temp = m._meta.get_field(h).verbose_name
                    else:
    
                        temp = h(self.model,is_head=True)
                    head_list.append(temp)
            flag = True
            # print(head_list,"----------->")
            return render(request,"list_view.html",{"obj":self.model,"data":data,"head_list":head_list})
    

      

    我们重点看下list_view视图函数

     def list_view(self,request):
            print(self.list_display)
            print("="*120)
            # models.app1testorm.objects.all().values_list()
    
            # if self.list_display:
            #     # 方式1,根据list_display获取指定字段数据
            #     # data = self.model.objects.all().values_list(*self.list_display)
            #     # print(data)
            #
            #     # 方式2:利用反射,去获取,然后自己组建列表返回给前端
            #     obj = getattr(self.model.objects.all()[0],self.list_display[0])
            #     print(obj)
            # else:
            #     list_display = ["object",]
            #     data = []
            #     obj_list = self.model.objects.all()
            #     for o in obj_list:
            #         temp = [o,]
            #         data.append(temp)
            data = []
            head_list = []
            flag = False
            for m in self.model.objects.all():
                temp = []
                for i in self.list_display:
                    if isinstance(i,str):
                        f = getattr(m,i)
    
                    else:
                        f = i(self.model,m)
    
                    temp.append(f)
                data.append(temp)
    
            # print(self.list_display)
            if not flag:
                for h in self.list_display:
    
                    if isinstance(h,str):
                        print(h)
                        temp = m._meta.get_field(h).verbose_name
                    else:
    
                        temp = h(self.model,is_head=True)
                    head_list.append(temp)
            flag = True
            # print(head_list,"----------->")
            return render(request,"list_view.html",{"obj":self.model,"data":data,"head_list":head_list})
    

      

     最后把表头和表身体的数据发送给前端渲染就可以了

     

    这里我一直不懂xadmin_class这个类为什么需要两个参数呢?这里我认为就一个参数就好了,而且我们没有传递site这个对象也是没问题,希望大家可以帮我答疑解惑一下

  • 相关阅读:
    辅助随笔:因知识点不足暂时错过的题目
    NOIP2019翻车前写(and 抄)过的代码
    NOIP2019翻车前计划以及日记
    Luogu P3706 [SDOI2017]硬币游戏
    Luogu P5296 [北京省选集训2019]生成树计数
    Luogu P3307 [SDOI2013]项链
    Gaussian整数
    Problem. S
    LOJ6696 复读机 加强版
    数据库约束
  • 原文地址:https://www.cnblogs.com/bainianminguo/p/9937737.html
Copyright © 2011-2022 走看看