Django 如何使用admin组件来对后台数据进行管理的?
在每个app下的admin.py文件中进行注册: from app名.models.py import 模型类名 from django.contrib import admin admin.site.register(模型类名) class 自定义配置类名(admin.ModelAdmin): list_display = ["字段名1","字段名1"] admin.site.register(模型类名,自定义配置类名)
Django admin如何实现后台数据管理的?(admin源码解析)
一、启动 django启动后,会加载settings中的INSTALLED_APPS from django.contrib import admin 在__init.py中: from django.contrib.admin.sites import AdminSite, site // 导入模块的实例化对象,此为单例模式 from django.utils.module_loading import autodiscover_modules def autodiscover(): autodiscover_modules('admin', register_to=site) //加载每一个app下的admin.py文件 # 优先执行哪个app下的admin.py 是由settings中的INSTALLED_APPS的加载顺序决定的
二、注册 admin.site.register(Author) class BookConfig(admin.ModelAdmin): pass admin.site.register(Book,BookConfig) admin.py---sites.py中: class AdminSite(object): def __init__(self): self._registry = {} def register(self,model,admin_class=None): if not admin_class: admin_class = ModelAdmin self._registry[model] = admin_class(model, self) site = AdminSite() admin.site._registry --> { <class 'django.contrib.auth.models.Group'>:<django.contrib.auth.admin.GroupAdmin object at 0x0000000003E70DD8>, <class 'django.contrib.auth.models.User'>:<django.contrib.auth.admin.UserAdmin object at 0x0000000003E9DCC0>, <class 'app01.models.Author'>:ModelAdmin(Author), <class 'app01.models.AuthorDetail'>:ModelAdmin(AuthorDetail), <class 'app01.models.Book'>: BookConfig(Book), <class 'app01.models.Publish'>:PublishConfig(Publish), } 在app下admin.py文件中注册,admin.site._registry中才会有此键值对。
三、设计url ##### 一级url分发 ##### urlpatterns = [ url(r"^my_admin/",([ url(r"^book/",app01_views.list_book), url(r"^publish/",app01_views.list_publish), url(r"^food/",app02_views.list_food), ],None,None)) ] ##### 二级url分发 ##### urlpatterns = [ url(r"^my_admin/",([ url(r"^book/",([ url(r"^$",app01_views.list_book), url(r"^add/$",app01_views.add_book), url(r"^(\d+)/change/$",app01_views.edit_book), url(r"^(\d+)/delete/$",app01_views.del_book), ],None,None)), url(r"^publish/",app01_views.list_publish), url(r"^food/",app02_views.list_food), ],None,None)) ] 在urls.py中: from django.conf.urls import url from django.contrib import admin from django.shortcuts import HttpResponse def listview(request): return HttpResponse("listview") def addview(request): return HttpResponse("addview") def changeview(request,id): return HttpResponse("changeview") def deleteview(request,id): return HttpResponse("deleteview") def get_urls_02(): res = [ url(r"^$",listview), url(r"^add/$",addview), url(r"^(\d+)/change/$",changeview), url(r"^(\d+)/delete/$",deleteview), ] return res def get_urls_01(): res = [] print("urls.py文件中admin.site._registry -->",admin.site._registry) """ urls.py文件中admin.site._registry --> { <class 'django.contrib.auth.models.Group'>: <django.contrib.auth.admin.GroupAdmin object at 0x0000000003E70E10>, <class 'django.contrib.auth.models.User'>: <django.contrib.auth.admin.UserAdmin object at 0x0000000003E9DCF8>, <class 'app01.models.Author'>: <django.contrib.admin.options.ModelAdmin object at 0x0000000003EB0940>, <class 'app01.models.AuthorDetail'>: <django.contrib.admin.options.ModelAdmin object at 0x0000000003EB0978>, <class 'app01.models.Book'>: <app01.admin.BookConfig object at 0x0000000003EB09B0>, <class 'app01.models.Publish'>: <app01.admin.PublishConfig object at 0x0000000003EB09E8>, <class 'app02.models.Food'>: <django.contrib.admin.options.ModelAdmin object at 0x0000000003EB07F0> } """ for model,config_obj in admin.site._registry.items(): print("模型类变量model-->",model) print("配置类对象config_obj-->",config_obj) model_name = model._meta.model_name # 获取字符串形式的模型类名 app_label = model._meta.app_label # 获取字符串形式的app名 print("model_name-->{},type(model_name)-->{}".format(model_name,type(model_name))) print("app_label-->{},type(model_name)-->{}".format(app_label,type(app_label))) """ 模型类变量model--> <class 'django.contrib.auth.models.Group'> 配置类对象config_obj--> auth.GroupAdmin model_name-->group,type(model_name)--><class 'str'> app_label-->auth,type(model_name)--><class 'str'> 模型类变量model--> <class 'django.contrib.auth.models.User'> 配置类对象config_obj--> auth.UserAdmin model_name-->user,type(model_name)--><class 'str'> app_label-->auth,type(model_name)--><class 'str'> 模型类变量model--> <class 'app01.models.Author'> 配置类对象config_obj--> app01.ModelAdmin model_name-->author,type(model_name)--><class 'str'> app_label-->app01,type(model_name)--><class 'str'> 模型类变量model--> <class 'app01.models.AuthorDetail'> 配置类对象config_obj--> app01.ModelAdmin model_name-->authordetail,type(model_name)--><class 'str'> app_label-->app01,type(model_name)--><class 'str'> 模型类变量model--> <class 'app01.models.Book'> 配置类对象config_obj--> app01.BookConfig model_name-->book,type(model_name)--><class 'str'> app_label-->app01,type(model_name)--><class 'str'> 模型类变量model--> <class 'app01.models.Publish'> 配置类对象config_obj--> app01.PublishConfig model_name-->publish,type(model_name)--><class 'str'> app_label-->app01,type(model_name)--><class 'str'> 模型类变量model--> <class 'app02.models.Food'> 配置类对象config_obj--> app02.ModelAdmin model_name-->food,type(model_name)--><class 'str'> app_label-->app02,type(model_name)--><class 'str'> """ add_url = url(r"^{}/{}/".format(app_label,model_name),(get_urls_02(),None,None)) res.append(add_url) return res urlpatterns = [ url(r"^my_admin/",(get_urls_01(),None,None)), ]
如何仿照admin实现一个自定义的增删改查的组件?
一、启动 1、创建一个与Django项目无关的,可以单独分离出来用在多个项目上的名称为my_admin的app: python manage.py startapp my_admin 2、创建两个与Django项目有关的两个app: python manage.py startapp app01 python manage.py startapp app02 3、在settings.py中的INSTALLED_APPS变量中添加: 'app01.apps.App01Config', 'app02.apps.App02Config', 'my_admin.apps.MyAdminConfig', 4、将my_admin、app01和app02中的admin.py文件全部删除,重新分别在app01和app02中添加myAdmin.py 5、app01下models.py中添加Book,Publish,AuthorDetail,Author类 6、app02下models.py中添加Food类 7、迁移数据库: python manage.py makemigrations python manage.py migrate 8、my_admin的app下有一个apps.py文件,在此文件中添加: from django.utils.module_loading import autodiscover_modules class MyAdminConfig(AppConfig): name = 'my_admin' def ready(self): autodiscover_modules("myAdmin")
二、注册 1、my_admin的app下创建一个python package的包,名称为service 2、在service文件夹下新建一个sites.py文件 3、sites.py中添加以下代码: class ModelMyAdmin(): list_display = [] def __init__(self,model): self.model = model class MyAdminSite(): def __init__(self): self._registry = {} def register(self,model,my_admin_class = None): if not my_admin_class: my_admin_class = ModelMyAdmin self._registry[model] = my_admin_class(model) site = MyAdminSite() 4、在app01下的myAdmin.py中注册模型类: from my_admin.service.sites import ModelMyAdmin,site from app01.models import Book,Publish,Author,AuthorDetail class BookConfig(ModelMyAdmin): list_display = ["title","publish_date","price"] site.register(Book,BookConfig) site.register(Publish) site.register(Author) site.register(AuthorDetail) print("app01下的site._registry-->",site._registry) 启动项目后,打印出此字典证明已经注册成功 { <class 'app01.models.Author'>: <my_admin.service.sites.ModelMyAdmin object at 0x0000000003EA70B8>, <class 'app01.models.AuthorDetail'>: <my_admin.service.sites.ModelMyAdmin object at 0x0000000003EB1B00>, <class 'app01.models.Book'>: <app01.myAdmin.BookConfig object at 0x0000000003EB1EB8>, <class 'app01.models.Publish'>: <my_admin.service.sites.ModelMyAdmin object at 0x0000000003EB1EF0> }
三、设计url 1、在urls.py文件中: from django.conf.urls import url from my_admin.service.sites import site urlpatterns = [ url(r'^my_admin/',site.urls), ] 2、在sites.py文件中的MyAdminSite类中继续添加一个urls方法: from django.conf.urls import url def get_urls_01(self): res = [] for model,config_obj in self._registry.items(): model_name = model._meta.model_name app_label = model._meta.app_label add_url = url(r'{}/{}/'.format(app_label,model_name),config_obj.urls) #config_obj:某个model的配置类(自定义配置类或者默认配置类)对象 res.append(add_url) return res @property def urls(self): return self.get_urls_01(),None,None 3、在sites.py文件中的ModelMyAdmin类中继续添加一个urls方法: from django.shortcuts import render def listview(self,request): print("self-->",self) # 当前访问模型类的配置类对象 print("self.model-->",self.model) # 当前访问模型类 data = self.model.objects.all() return render(request,"listview.html",{"data_list":data}) def addview(self,request): return HttpResponse("addview") def changeview(self,request, id): return HttpResponse("changeview") def deleteview(self,request, id): return HttpResponse("deleteview") def get_urls_02(self): res = [ url(r'^$',self.listview) url(r'^add/$',self.addview) url(r'^(\d+)/change/$',self.changeview) url(r'^(\d+)/delete/$',self.deleteview ] return res @property def urls(self): return self.get_urls_02(),None,None
为什么要将get_urls_02的方法写入到ModelMyAdmin类中,而不写在MyAdminSite类中?
将get_urls_02写入到MyAdminSite类中,由于单例模式造成返回的是同一个页面,如果是简单的返回一个HttpResponse对象,是可以的;
但是现实需求是不同的表要展示不同的视图数据而且不同的表要有不同的配置信息,故需要写入在ModelMyAdmin类中。
如何仿照admin实现一个自定义的增删改查的组件?
一、启动 1、创建一个与Django项目无关的,可以单独分离出来用在多个项目上的名称为my_admin的app: python manage.py startapp my_admin 2、创建两个与Django项目有关的两个app: python manage.py startapp app01 python manage.py startapp app02 3、在settings.py中的INSTALLED_APPS变量中添加: 'app01.apps.App01Config', 'app02.apps.App02Config', 'my_admin.apps.MyAdminConfig', 4、将my_admin、app01和app02中的admin.py文件全部删除,重新分别在app01和app02中添加myAdmin.py 5、app01下models.py中添加Book,Publish,AuthorDetail,Author类 6、app02下models.py中添加Food类 7、迁移数据库: python manage.py makemigrations python manage.py migrate 8、my_admin的app下有一个apps.py文件,在此文件中添加: from django.utils.module_loading import autodiscover_modules class MyAdminConfig(AppConfig): name = 'my_admin' def ready(self): autodiscover_modules("myAdmin")
二、注册 1、my_admin的app下创建一个python package的包,名称为service 2、在service文件夹下新建一个sites.py文件 3、sites.py中添加以下代码: class ModelMyAdmin(): list_display = [] def __init__(self,model): self.model = model class MyAdminSite(): def __init__(self): self._registry = {} def register(self,model,my_admin_class = None): if not my_admin_class: my_admin_class = ModelMyAdmin self._registry[model] = my_admin_class(model) site = MyAdminSite() 4、在app01下的myAdmin.py中注册模型类: from my_admin.service.sites import ModelMyAdmin,site from app01.models import Book,Publish,Author,AuthorDetail class BookConfig(ModelMyAdmin): list_display = ["title","publish_date","price"] site.register(Book,BookConfig) site.register(Publish) site.register(Author) site.register(AuthorDetail) print("app01下的site._registry-->",site._registry) 启动项目后,打印出此字典证明已经注册成功 { <class 'app01.models.Author'>: <my_admin.service.sites.ModelMyAdmin object at 0x0000000003EA70B8>, <class 'app01.models.AuthorDetail'>: <my_admin.service.sites.ModelMyAdmin object at 0x0000000003EB1B00>, <class 'app01.models.Book'>: <app01.myAdmin.BookConfig object at 0x0000000003EB1EB8>, <class 'app01.models.Publish'>: <my_admin.service.sites.ModelMyAdmin object at 0x0000000003EB1EF0> }
三、设计url 1、在urls.py文件中: from django.conf.urls import url from my_admin.service.sites import site urlpatterns = [ url(r'^my_admin/',site.urls), ] 2、在sites.py文件中的MyAdminSite类中继续添加一个urls方法: from django.conf.urls import url def get_urls_01(self): res = [] for model,config_obj in self._registry.items(): model_name = model._meta.model_name app_label = model._meta.app_label add_url = url(r'{}/{}/'.format(app_label,model_name),config_obj.urls) #config_obj:某个model的配置类(自定义配置类或者默认配置类)对象 res.append(add_url) return res @property def urls(self): return self.get_urls_01(),None,None 3、在sites.py文件中的ModelMyAdmin类中继续添加一个urls方法: from django.shortcuts import render def listview(self,request): print("self-->",self) # 当前访问模型类的配置类对象 print("self.model-->",self.model) # 当前访问模型类 data = self.model.objects.all() return render(request,"listview.html",{"data_list":data}) def addview(self,request): return HttpResponse("addview") def changeview(self,request, id): return HttpResponse("changeview") def deleteview(self,request, id): return HttpResponse("deleteview") def get_urls_02(self): res = [ url(r'^$',self.listview) url(r'^add/$',self.addview) url(r'^(\d+)/change/$',self.changeview) url(r'^(\d+)/delete/$',self.deleteview ] return res @property def urls(self): return self.get_urls_02(),None,None
为什么要将get_urls_02的方法写入到ModelMyAdmin类中,而不写在MyAdminSite类中?
将get_urls_02写入到MyAdminSite类中,由于单例模式造成返回的是同一个页面,如果是简单的返回一个HttpResponse对象,是可以的;
但是现实需求是不同的表要展示不同的视图数据而且不同的表要有不同的配置信息,故需要写入在ModelMyAdmin类中。