zoukankan      html  css  js  c++  java
  • 自定义Xadmin

    1.启动Xadmin

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'Xadmin.apps.XadminConfig',
        'app01.apps.App01Config',
        'app02.apps.App02Config',
    ]
    执行流程:
    1.在启动Django后,按app顺序进行加载。先加载 'django.contrib.admin',Django自身生成admi.site单例对象,生成user和group两张表
    加载到'Xadmin.apps.XadminConfig',执行Xadmin中apps文件中的XadminConfig
    apps中的代码:
    from django.apps import AppConfig
    class XadminConfig(AppConfig):
    name = 'Xadmin'
    2.XadminConfig中有个raedy方法,会自动执行,Django默认去读取自身和其他app的admin文件,如在相应的app的admin文件中输入
    print("xadmin") print("app01")print("app02")进行测试
    启动django后,就会根据加载顺序打印出结果:
    xadmin
    app01
    app02
    3.在执行第一个app的admin文件时,
    from django.contrib import admin 会执行admin,打开admin源码分析:
    admin源码:
    from django.utils.module_loading import autodiscover_modules
    def autodiscover():
    autodiscover_modules('admin', register_to=site) #启动admin
    4.打开site site = AdminSite() 因此在执行admin文件时就生成了app应用的单例对象admin.site,在扫描其他app的admin文件时
    由于from django.contrib import admin已经加载过,因此直接拿到第一个app生成的单例对象

    2.配置Xadmin下的apps文件

    我们可以自己设置函数
    如:在类中添加
    def ready(self):
    print("ok") 在启动django,加载到Xadmin的app文件时,自动执行ready函数,打印出"ok"
    Django加载时默认读取其他app的admin文件,因此要设置在执行这个文件时,去读取其他app的Xadmin文件.根据admin文件去写
    from django.apps import AppConfig
    from django.utils.module_loading import autodiscover_modules
    class XadminConfig(AppConfig):
    name = 'Xadmin'
    def ready(self):
    autodiscover_modules('Xadmin')
    #在加载app文件时时读取自身和其他app的xadmin文件。由于是自定义admin,目的是让其他app执行自定义的admin,因此删除掉Xadmin下的admin
    测试:在app01和app02分别新建Xadmin文件,输入print("Xadmin app01")和print("Xadmin app01")打印后:
    admin app01 #在admin文件中的测试
    admin app02
    Xadmin app01
    Xadmin app02
    原因:'django.contrib.admin',会先执行,因此先加载app中的admin文件,将自带的admin关掉就可以了
    Xadmin app01
    Xadmin app02

    3.配置Xadmin的注册,新建个文件夹放Xadmin.py文件,代码仿着admin.py文件写

    #根据ModelAdmin源码写
    class Modelxadmin(object):
        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:
                admin_class = Modelxadmin #根据AdminSite源码,定义admin_class类
        self._registry[model] = admin_class(model, self)
    site=XadminSite() #生成单例对象

    4.在app中的xadmin文件中引入Xadmin,进行注册模型表

    app01 Xadmin.py
    from Xadmin.service.Xadmin import site
    from app01 import models
    site.register(models.Book)
    site.register(models.Publish)
    site.register(models.Author)
    site.register(models.AuthorDetail)
    app02 Xadmin.py
    from Xadmin.service.Xadmin import site
    from app02 import models
    site.register(models.Order)
    print(site._registry)  #结果有五个表

    5.设计路由:

    参考admin的路由设计
    urlpatterns = [
    url(r'^admin/', admin.site.urls), admin.site是Adminsite类的对象,urls是 AdminSite类中的一个方法
    ]
    查看AdminSite源码:找到urls方法,分析其流程。执行urls方法后,执行get_urls方法,在get_urls设置路由
    admin的路由源码:
    @property
    def urls(self):
        return self.get_urls(), 'admin', self.name #结果是个元祖即等同于url(r'^admin/',(get_urls(),None,None))
    def get_urls(self):
        from django.conf.urls import url, include
        def wrap(view, cacheable=False):
            def wrapper(*args, **kwargs):
                return self.admin_view(view, cacheable)(*args, **kwargs)
            wrapper.admin_site = self
            return update_wrapper(wrapper, view)
        # Admin-site-wide views.
        urlpatterns = [
            url(r'^$', wrap(self.index), name='index'),
            url(r'^login/$', self.login, name='login'),
            url(r'^logout/$', wrap(self.logout), name='logout'),
            url(r'^password_change/$', wrap(self.password_change, cacheable=True), name='password_change'),
            url(r'^password_change/done/$', wrap(self.password_change_done, cacheable=True),
                name='password_change_done'),
            url(r'^jsi18n/$', wrap(self.i18n_javascript, cacheable=True), name='jsi18n'),
            url(r'^r/(?P<content_type_id>d+)/(?P<object_id>.+)/$', wrap(contenttype_views.shortcut),
                name='view_on_site'),
    View Code

    设置Xadmin路由:

    1.from Xadmin.service.Xadmin import site
    urlpatterns = [
    #根据admin路由设置方式设置Xadmin路由
    url(r'^Xadmin/', site.urls),
    ]
    2.在Xadmin中设置urls方法
     class XadminSite(object):
            def __init__(self, name='admin'):
                self._registry = {}
            def register(self, model, admin_class=None, **options):
                if not admin_class:
                    admin_class = Modelxadmin #根据AdminSite源码,定义夜歌admin_class类
                self._registry[model] = admin_class(model, self)
            def list_view(self,request):
                return HttpResponse("这是查看的网页")
            def add_view(self,request):
                return HttpResponse("这是添加的网页")
            def change_view(self,request, id):
                return HttpResponse("这是编辑的网页")
            def del_view(self,request, id):
                return HttpResponse("这是删除的网页")
            def get_url_2(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+)/del/$", self.del_view))
                return temp
            @property
            def urls2(self):
                return self.get_url_2(), None, None
            def get_urls(self):
                temp = []
                print(self._registry)
                for model, admin_class in self._registry.items():
                    app_name = model._meta.app_label  # 拿到app的名字
                    model_name = model._meta.model_name  # 拿到字符串类型的表名
                    temp.append(url(r"^{}/{}/".format(app_name, model_name), self.urls2))
                return temp
            @property
            def urls(self): #self就是XadminSite单例出来的对象
                return self.get_urls(), None, None
    View Code

    6.获取数据:

    将二级路由放到XadminSite类之后,即创建的book,publish等模型表在Xadmin中所有的配置都一样。
    同时在进行相应的表的数据查询时,比较困难 为了不同的模型表显示不同的效果,将二级路由放到Modelxadmin中
     class Modelxadmin(object):
            def __init__(self,model,site):  #如果传的是book,model就是book 传的是publish,model就是publiah
                self.model=model
                self.site=site
            def list_view(self, request):
                print(self.model)  #用户调用的哪张表,self.model就是哪张表  <class 'app02.models.Order'>
                print(request.path_info)  # /Xadmin/app01/publish/
                data_list=self.model.objects.all()
                # return HttpResponse("这是查看的网页")
                return render(request,"list.html",{"data_list":data_list})
            def add_view(self, request):
                return HttpResponse("这是添加的网页")
            def change_view(self, request, id):
                return HttpResponse("这是编辑的网页")
            def del_view(self, request, id):
                return HttpResponse("这是删除的网页")
            def get_url_2(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+)/del/$", self.del_view))
                return temp
            @property
            def urls2(self):
                return self.get_url_2(), None, None
        class XadminSite(object):
            def get_urls(self):
                temp = []
                print(self._registry)
                for model, xadmin_class in self._registry.items(): #xadmin_class=admin_class(model, self)是注册的模型表对象 ModelAdmin(Book)
                    app_name = model._meta.app_label  # 拿到app的名字
                    model_name = model._meta.model_name  # 拿到字符串类型的表名
                    temp.append(url(r"^{}/{}/".format(app_name, model_name), xadmin_class.urls2))
                    #此时的路由表示
                      url(r"app01/book",ModelXadmin(Book,site).urls2)
                      url(r"app01/publish",ModelXadmin(Publish,site).urls2)
                      url(r"app02/order",ModelXadmin(Order,site).urls2)
                return temp
    View Code
  • 相关阅读:
    给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
    11
    实战 迁移学习 VGG19、ResNet50、InceptionV3 实践 猫狗大战 问题
    tx2系统备份与恢复
    如何在Ubuntu 18.04上安装和卸载TeamViewer
    bzoj 3732 Network (kruskal重构树)
    bzoj2152 聪聪可可 (树形dp)
    牛客 216D 消消乐 (二分图最小点覆盖)
    牛客 197E 01串
    Wannafly挑战赛23
  • 原文地址:https://www.cnblogs.com/chongdongxiaoyu/p/9177721.html
Copyright © 2011-2022 走看看