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
  • 相关阅读:
    记一次线上网络问题排查
    记服务器上session设置引起的OutofMemory
    由DateFormat引起的线程安全问题
    十二周总结
    团队开发冲刺第十天
    团队开发冲刺第九天
    团队开发冲刺第八天
    团队开发冲刺第七天
    十二周总结
    团队开发冲刺第六天
  • 原文地址:https://www.cnblogs.com/chongdongxiaoyu/p/9177721.html
Copyright © 2011-2022 走看看