Django模块Admin实现

一:Django中的admin

admin提供Django项目中的超级用户后台管理,可以很方便的在后台操作数据库。同时提供个性化的展示,其路由的设计也十分有特点  

在后台管理中:admin应用给每一个表实现四个页面,增、删、改、查。

个性化展示:可以自定义每张表的个性化展示配置

from django.contrib.admin import ModelAdmin #表的个性化配置需要导入的父类
#下面是Django中ModelAdmin的一部分源码
class ModelAdmin(BaseModelAdmin): "Encapsulates all admin options and functionality for a given model." list_display = ('__str__',) # 可以配置查询页面的显示字段,通过继承ModelAdmin,覆盖掉源码中的list_display list_display_links = () # 可以通过这个配置跳转的链接 list_filter = () # 可以通过这个配置快捷查询,一般会放置在一对多,多对多字段上才有意义 list_select_related = False list_per_page = 100 list_max_show_all = 200 list_editable = () search_fields = () date_hierarchy = None save_as = False save_as_continue = True save_on_top = False paginator = Paginator preserve_filters = True inlines = []

 路由设计

url(r'^admin/', admin.site.urls),# 所有的路由入口

urlpatterns += [
url(r'^%s/%s/' % (model._meta.app_label, model._meta.model_name), include(model_admin.urls)),
]
# 二级路由

model._meta.app_label:model_class对象所在的App
model._meta.model_name:model_class的名称(小写)

urlpatterns = [
url(r'^add/$', wrap(self.add_view), name='%s_%s_add' % info),
url(r'^(.+)/history/$', wrap(self.history_view), name='%s_%s_history' % info),
url(r'^(.+)/delete/$', wrap(self.delete_view), name='%s_%s_delete' % info),
url(r'^(.+)/change/$', wrap(self.change_view), name='%s_%s_change' % info),
# For backwards compatibility (was the change url before 1.9)
url(r'^(.+)/$', wrap(RedirectView.as_view(
pattern_name='%s:%s_%s_change' % ((self.admin_site.name,) + info)
))),
]
# 三级路由

二:设计的实现

根据admin的源码,可以知道,实现主要的功能需要三个方面:

1:启动

执行每一个app下的admin.py 文件

from django.utils.module_loading import autodiscover_modules  # 导入启动模块
autodiscover_modules('admin', register_to=site) # 执行所有的admin.py文件

2:将应用的中的model_class注册到admin应用中

            class AdminSite(object):
                 def __init__(self, name='admin'):
                       self._registry = {} 
                 def register(self, model_or_iterable, admin_class=None, **options):
                      if not admin_class:
                             admin_class = ModelAdmin   # 配置类
                             
                      self._registry[model] = admin_class(model, self)
                      
                      # {Book:BookConfig(Book),Publish:ModelAdmin(Publish)}
            
            site=AdminSite()

个性化配置的注册方式

class BookConfig(ModelAdmin):
    list_display=["",]
    admin.site.register(Book,BookConfig)
    admin.site.register(Publish)

3:url的设计

目的:为每一个注册的model设计增删该查4个url
http://127.0.0.1:8000/admin/app01/book/
http://127.0.0.1:8000/admin/app01/book/add
http://127.0.0.1:8000/admin/app01/book/1/change/
http://127.0.0.1:8000/admin/app01/book/1/delete/

三:自实现的类似admin的应用

新建一个Django工程
在Django建一个App,暂且命名为stark

根据上面的设计思路完成设计

启动模块:项目启动后执行stark.py

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

class StarkConfig(AppConfig):
    name = 'stark'

    def ready(self):
        autodiscover_modules('stark')

把App stark注册到项目settings中去

在其他App中导入stark并把model中的class注册到stark中

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


class BookConfig(ModelStark):
    list_display = ['title','price','publishDate']


site.register(models.Book,BookConfig)

程序的实现逻辑

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# Author:YiJun
from django.conf.urls import url
from app01 import models
from django.shortcuts import HttpResponse, redirect, render


class ModelStark():  # 配置类对象
    list_display = []  # 父类中的默认参数

    def __init__(self, model):
        self.model = model

    def list_view(self, request):   # 查看页面的视图渲染
        if self.list_display:
            query_set = self.model.objects.all().values(*self.list_display)
        else:
            query_set = self.model.objects.all()
        return render(request, 'server/list_view.html', {'query_set': query_set, 'list_display': self.list_display})
def get_url2(self):  # 三级路由的实现
        url2 = ([
                    url("^$", self.list_view),
                    url("add/$", self.add_view),
                    url("(\d+)/change/$", self.change_view),
                    url("(\d+)/delete/$", self.delete_view),
                ], None, None
        )
        return url2

    @property
    def urls2(self):
        return self.get_url2()


class StarkSite(object): # stark应用的程序逻辑

    def __init__(self, name='admin'):
        self._registry = {}

    def register(self, model, stark_class=None, **options): # model_class的注册方法
        if not stark_class:
            stark_class = ModelStark  # 配置类
        self._registry[model] = stark_class(model)  # 每个model_class都有一个配置类的对象

    def get_urls(self):  # 一级路由配置
        temp = []
        for model_class, config_obj in self._registry.items():
            model_name = model_class._meta.model_name
            app_label = model_class._meta.app_label
            temp.append(url(r'^%s/%s/' % (app_label, model_name), config_obj.urls2))
        return temp

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


site = StarkSite() # 实例化出一个stark的对象,注册的时候,其他应用的调用都是同一个对象,采用的是单例模式
posted @ 2018-07-20 20:18  Leslie-x  阅读(207)  评论(0)    收藏  举报