自定义Django_admin

自定义admin同django_admin,三步走

一,启动

django启动加载settings.py中的 INSTALLED_APPS 下注册的每一个app,在django_admin中为了让django加载每一个app中的admin.py文件,调用了

autodiscover_modules('admin', register_to=site)

该方法循环加载了每一个app中的admin.py中我们注册的模型表类和配置类;

那么我们仿照django_admin实现一下:

先创建一个stark的app,然后在 INSTALLED_APPS 中注册,这里需要调用一个方法:

在注册的stark下的apps.py中,添加ready方法,在注册完stark后就能自动执行该方法下的代码,在该方法去调用 autodiscover_modules('stark', register_to=site),

from django.apps import AppConfig
from django.utils.module_loading import autodiscover_modules

from stark.service.sites import site


class StarkConfig(AppConfig):
    name = 'stark'

    def ready(self):
        autodiscover_modules('stark', register_to=site)

ok,启动完毕!

二,注册

直接仿照django_admin,现在自己的组件stark文件夹下,新建一个sites.py,(当然这个sites.py放在那个目录都可以,而且名字也无所谓叫什么),这里我们的文件结构如下:

在sites.py中创建我们的stark组件的全局类AdminSite(类比django_admin中的AdminSite()),以及我们的默认配置类ModelStark(类比django_admin中的ModelAdmin),还有单例对象

class ModelStark(object):
    """
    默认的配置类
    """
    list_display = []

    def __init__(self, model, admin_class):
        self.model = model  # 这一步完成了把模型表赋值在self中,即self.model
        # self.admin_class = admin_class
class AdminSite(object):
    """
    stark组件的全局类
    """

    def __init__(self):
        self._registry = {}  # 设置 那个存储不同app注册的模型表

    def register(self, model, admin_class=None):

        # 配置默认的样式类,为我们自己的ModelStark类
        if not admin_class:
            admin_class = ModelStark

        self._registry[model] = admin_class(model, self)  # 仿照admin,把所有的注册了的 模型表和配置类组成的键值对 添加到自己全局类的那个字典中
# 单例模式, 每一个app下的stark.py中注册时都是同一个site对象,调用的同一个_registry那个字典,往里面添加键值对
site = AdminSite()

然后和注册django_admin一样需要在我们的每个app下的stark.py中注册:

from app01 import models
from stark.service.sites import site, ModelStark


class BookConfig(ModelStark):  # 自定义配置类
    list_display = ["title", "price"]


site.register(models.Book, BookConfig)
site.register(models.Publish)  # 没有传入自定义配置类,使用默认的配置类ModelStark
site.register(models.Author)  # 没有传入自定义配置类,使用默认的配置类ModelStark
site.register(models.AuthorDetail)  # 没有传入自定义配置类,使用默认的配置类ModelStark

注册完毕!

三,URL配置

仿照django的url分发,自定义url分发:

from django.conf.urls import url
from django.contrib import admin

from stark.service.sites import site  # 导入我们的那个单例对象

urlpatterns = [
    url(r'^admin/', admin.site.urls),

    # 自定义的stark组件(类似django_admin)
    url(r'^stark/', site.urls),  调用全局类中的静态方法urls
]

所以我们的全局类要这么写:

class AdminSite(object):
    """
    stark组件的全局类
    """

    def __init__(self):
        self._registry = {}  # 设置 那个存储不同app注册的模型表

    def register(self, model, admin_class=None):

        # 配置默认的样式类,为我们自己的ModelStark类
        if not admin_class:
            admin_class = ModelStark

        self._registry[model] = admin_class(model, self)

    def get_urls(self):
        temp = []
        for model, config_obj in self._registry.items():
            model_name = model._meta.model_name  # 拿到模型表名
            app_name = model._meta.app_label  # 拿到app名称
            temp.append(url(r"^{}/{}/".format(app_name, model_name), config_obj.urls))
            # 这里注意,是使用的config_obj.urls,config_obj就是我们的配置类,把二级分发路由写到配置类中,
            # 把对应的视图函数也写在配置类中,这样我们在调用试图函数时,self就是我们的配置类(config_obj),
            # 而且,每一次循环就是其对应的表的配置类,
            # 而self.model就是我们在实例化配置类的时候添加进去的,也就是我们对应的模型表类
        return temp

    @property
    def urls(self):  # 上面url就是调用的这个静态方法
        return self.get_urls(), None, None  # 路由分发必须返回三个参数: [], None, None

二级路由是放在配置类中的,由配置类调用配置类中的urls静态方法,同时把我们的视图函数先写在配置类中,所以我们的配置类要这么写

from django.conf.urls import url
from django.shortcuts import HttpResponse, redirect, render

# 仿照django_admin自定义一个类似的组件
class ModelStark(object):
    """
    默认的配置类
    """
    list_display = []

    def __init__(self, model, admin_class):
        self.model = model  # 这一步完成了把模型表赋值在self中,即self.model
        # self.admin_class = admin_class

    def view_list(self, request):
        # print(self)  # self就是配置类本身
        # print(self.model)  # self.model就是模型表
        all_data = self.model.objects.all()
        # print(self.list_display)
        return render(request, "view_list.html", {"all_data": all_data})

    def add(self, request):
        return HttpResponse("add")

    def delete(self, request, pk):
        return HttpResponse("delete")

    def change(self, request, pk):
        return HttpResponse("change")


    def get_urls(self):
        temp = [
            url(r"^$", self.view_list),
            url(r"^add/$", self.add),
            url(r"^(\d+)/change/$", self.change),
            url(r"^(\d+)/delete/$", self.delete),
        ]
        return temp

    @property
    def urls(self):  # 配置类调用就是这个urls方法
        return self.get_urls(), None, None
#!/usr/bin/env python
# -*- coding:utf8 -*-
from django.conf.urls import url
from django.shortcuts import HttpResponse, redirect, render



# 仿照django_admin自定义一个类似的组件
class ModelStark(object):
    """
    默认的配置类
    """
    list_display = []

    def __init__(self, model, admin_class):
        self.model = model  # 这一步完成了把模型表赋值在self中,即self.model
        # self.admin_class = admin_class

    def view_list(self, request):
        # print(self)  # self就是配置类本身
        # print(self.model)  # self.model就是模型表
        all_data = self.model.objects.all()
        # print(self.list_display)
        return render(request, "view_list.html", {"all_data": all_data})

    def add(self, request):
        return HttpResponse("add")

    def delete(self, request, pk):
        return HttpResponse("delete")

    def change(self, request, pk):
        return HttpResponse("change")


    def get_urls(self):
        temp = [
            url(r"^$", self.view_list),
            url(r"^add/$", self.add),
            url(r"^(\d+)/change/$", self.change),
            url(r"^(\d+)/delete/$", self.delete),
        ]
        return temp

    @property
    def urls(self):
        return self.get_urls(), None, None


class AdminSite(object):
    """
    stark组件的全局类
    """

    def __init__(self):
        self._registry = {}  # 设置 那个存储不同app注册的模型表

    def register(self, model, admin_class=None):

        # 配置默认的样式类,为我们自己的ModelStark类
        if not admin_class:
            admin_class = ModelStark

        self._registry[model] = admin_class(model, self)

    def get_urls(self):
        temp = []
        for model, config_obj in self._registry.items():
            model_name = model._meta.model_name  # 拿到模型表名
            app_name = model._meta.app_label  # 拿到app名称
            temp.append(url(r"^{}/{}/".format(app_name, model_name), config_obj.urls))
            # 这里注意,是使用的config_obj.urls,config_obj就是我们的配置类,把二级分发路由写到配置类中,
            # 把对应的视图函数也写在配置类中,这样我们在调用试图函数时,self就是我们的配置类(config_obj),
            # 而且,每一次循环就是其对应的表的配置类,
            # 而self.model就是我们在实例化配置类的时候添加进去的,也就是我们对应的模型表类
        return temp

    @property
    def urls(self):
        return self.get_urls(), None, None  # 路由分发必须返回三个参数: [], None, None


# 单例模式, 每一个app下的stark.py中注册时都是同一个site对象,调用的同一个_registry那个字典,往里面添加键值对
site = AdminSite()
这就是我们的sites.py

这样访问以下的url,就能返回我们想要的结果了:

/stark/app01/book/add/  #
/stark/app01/book/1/delete/  #
/stark/app01/book/1/change/  #
/stark/app01/book/  #


/stark/app01/publish/add/  #
/stark/app01/publish/1/delete/  #
/stark/app01/publish/1/change/  #
/stark/app01/publish/  #

........等等所有我们注册的表

猜你喜欢

转载自www.cnblogs.com/glh-ty/p/9550059.html
今日推荐