Cet article présente principalement en détail l'utilisation et l'analyse du code source du composant admin de Django. Maintenant, je le partage avec vous. Les amis dans le besoin peuvent se référer au
Composant admin Utilisation de
Django fournit des outils de gestion basés sur le Web. Les outils de gestion automatisée de Django font partie de django.contrib. Vous pouvez le voir dans INSTALLED_APPS dans les paramètres du projet.py :# Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', "app01" ]
Outil de gestion des activations
Habituellement, nous le définirons automatiquement dans urls.py lors de la génération du projet,from django.conf.urls import url from django.contrib import admin urlpatterns = [ url(r'^admin/', admin.site.urls), ]
Utilisez l'outil de gestion
Démarrez le serveur de développement, puis visitez http://127.0.0.1:8000/admin/ dans le navigateur pour obtenir l'interface de connexion . Vous pouvez créer un superutilisateur via la commande python manage.py createsuperuser. Pour que l'interface d'administration puisse gérer un certain modèle de données, nous devons d'abord enregistrer le modèle de données auprès de l'administrateurfrom django.db import models class Author(models.Model): name=models.CharField( max_length=32) age=models.IntegerField() def __str__(self): return self.name class Publish(models.Model): name=models.CharField( max_length=32) email=models.EmailField() def __str__(self): return self.name class Book(models.Model): title = models.CharField( max_length=32) publishDate=models.DateField() price=models.DecimalField(max_digits=5,decimal_places=2) publisher=models.ForeignKey(to="Publish") authors=models.ManyToManyField(to='Author') def __str__(self): return self.title
Personnalisation de l'administrateur
Dans admin.py, il vous suffit d'enregistrer une certaine classe dans Mode pour réaliser la fonction d'ajout, de suppression, de modification et d'archivage dans Admin, telle que :
admin.site.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin): list_display = ('user', 'pwd',) admin.site.register(models.UserInfo, UserAdmin) # 第一个参数可以是列表
@admin.register(models.UserInfo) # 第一个参数可以是列表 class UserAdmin(admin.ModelAdmin): list_display = ('user', 'pwd',)
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): list_display = ('user', 'pwd', 'xxxxx') def xxxxx(self, obj): return "xxxxx"
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): list_display = ('user', 'pwd', 'xxxxx') list_display_links = ('pwd',)
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): list_display = ('user', 'pwd','ug',) list_editable = ('ug',)
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): search_fields = ('user', 'pwd')
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): date_hierarchy = 'ctime'
class UserInfoInline(admin.StackedInline): # TabularInline extra = 0 model = models.UserInfo class GroupAdminMode(admin.ModelAdmin): list_display = ('id', 'title',) inlines = [UserInfoInline, ]
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): # 定制Action行为具体方法 def func(self, request, queryset): print(self, request, queryset) print(request.POST.getlist('_selected_action')) func.short_description = "中文显示自定义Actions" actions = [func, ] # Action选项都是在页面上方显示 actions_on_top = True # Action选项都是在页面下方显示 actions_on_bottom = False # 是否显示选择个数 actions_selection_counter = True
add_form_template = None change_form_template = None change_list_template = None delete_confirmation_template = None delete_selected_confirmation_template = None object_history_template = None
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): raw_id_fields = ('FK字段', 'M2M字段',)
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): fields = ('user',)
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): exclude = ('user',)
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): readonly_fields = ('user',)
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): fieldsets = ( ('基本数据', { 'fields': ('user', 'pwd', 'ctime',) }), ('其他', { 'classes': ('collapse', 'wide', 'extrapretty'), # 'collapse','wide', 'extrapretty' 'fields': ('user', 'pwd'), }), )
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): filter_vertical = ("m2m字段",) # 或filter_horizontal = ("m2m字段",)
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): ordering = ('-id',) 或 def get_ordering(self, request): return ['-id', ]
radio_fields = {"ug": admin.VERTICAL} # 或admin.HORIZONTAL
from app01 import models from django.forms import ModelForm from django.forms import fields class MyForm(ModelForm): others = fields.CharField() class Meta: model = models = models.UserInfo fields = "__all__" @admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): form = MyForm
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): empty_value_display = "列数据为空时,默认显示" list_display = ('user','pwd','up') def up(self,obj): return obj.user up.empty_value_display = "指定列数据为空时,默认显示"
from django.contrib import admin # Register your models here. from .models import * class BookInline(admin.StackedInline): # TabularInline extra = 0 model = Book class BookAdmin(admin.ModelAdmin): list_display = ("title",'publishDate', 'price',"foo","publisher") list_display_links = ('publishDate',"price") list_filter = ('price',) list_editable=("title","publisher") search_fields = ('title',) date_hierarchy = 'publishDate' preserve_filters=False def foo(self,obj): return obj.title+str(obj.price) # 定制Action行为具体方法 def func(self, request, queryset): print(self, request, queryset) print(request.POST.getlist('_selected_action')) func.short_description = "中文显示自定义Actions" actions = [func, ] # Action选项都是在页面上方显示 actions_on_top = True # Action选项都是在页面下方显示 actions_on_bottom = False # 是否显示选择个数 actions_selection_counter = True change_list_template="my_change_list_template.html" class PublishAdmin(admin.ModelAdmin): list_display = ('name', 'email',) inlines = [BookInline, ] admin.site.register(Book, BookAdmin) # 第一个参数可以是列表 admin.site.register(Publish,PublishAdmin) admin.site.register(Author)
analyse du code source de l'administrateur
Singleton PatternSingleton Pattern est une conception logicielle couramment utilisée modèle L'objectif principal de ce modèle est de garantir qu'une seule instance d'une certaine classe existe. Les objets Singleton sont utiles lorsque vous souhaitez qu'une seule instance d'une certaine classe apparaisse dans l'ensemble du système. Par exemple, les informations de configuration d'un programme serveur sont stockées dans un fichier et le client lit les informations du fichier de configuration via une classe AppConfig. Si le contenu du fichier de configuration doit être utilisé à plusieurs endroits lors de l'exécution du programme, c'est-à-dire que des instances de l'objet AppConfig doivent être créées à plusieurs endroits, ce qui conduira à l'existence de plusieurs objets d'instance AppConfig. dans le système, ce qui gaspillera sérieusement les ressources de mémoire, surtout si le fichier de configuration contient beaucoup de contenu. En fait, pour une classe comme AppConfig, nous espérons qu'un seul objet instance existe pendant l'exécution du programme. En Python, nous pouvons utiliser diverses méthodes pour implémenter le modèle singleton :为了使类只能出现一个实例,我们可以使用 __new__ 来控制实例的创建过程,代码如下:
class Singleton(object): _instance = None def __new__(cls, *args, **kw): if not cls._instance: cls._instance = super(Singleton, cls).__new__(cls, *args, **kw) return cls._instance class MyClass(Singleton): a = 1
在上面的代码中,我们将类的实例和一个类变量 _instance 关联起来,如果 cls._instance 为 None 则创建实例,否则直接返回 cls._instance 。
执行情况如下:
>>> one = MyClass()
>>> two = MyClass()
>>> one == two
True
>>> one is two
True
>>> id(one), id(two)
(4303862608, 4303862608)
(2)使用模块
其实, Python 的模块就是天然的单例模式 ,因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。如果我们真的想要一个单例类,可以考虑这样做:
# mysingleton.py class My_Singleton(object): def foo(self): pass my_singleton = My_Singleton()
将上面的代码保存在文件 mysingleton.py 中,然后这样使用:
from mysingleton import my_singleton my_singleton.foo()
admin执行流程
<1> 循环加载执行所有已经注册的app中的admin.py文件
def autodiscover(): autodiscover_modules('admin', register_to=site)
<2> 执行代码
#admin.py class BookAdmin(admin.ModelAdmin): list_display = ("title",'publishDate', 'price') admin.site.register(Book, BookAdmin) admin.site.register(Publish)
<3> admin.site
这里应用的是一个单例模式,对于AdminSite类的一个单例模式,执行的每一个app中的每一个admin.site都是一个对象
<4> 执行register方法
admin.site.register(Book, BookAdmin) admin.site.register(Publish)
class ModelAdmin(BaseModelAdmin):pass def register(self, model_or_iterable, admin_class=None, **options): if not admin_class: admin_class = ModelAdmin # Instantiate the admin class to save in the registry self._registry[model] = admin_class(model, self)
到这里,注册结束!
<5> admin的URL配置
urlpatterns = [ url(r'^admin/', admin.site.urls), ]
class AdminSite(object): def get_urls(self): from django.conf.urls import url, include urlpatterns = [] # Add in each model's views, and create a list of valid URLS for the # app_index valid_app_labels = [] for model, model_admin in self._registry.items(): urlpatterns += [ url(r'^%s/%s/' % (model._meta.app_label, model._meta.model_name), include(model_admin.urls)), ] if model._meta.app_label not in valid_app_labels: valid_app_labels.append(model._meta.app_label) return urlpatterns @property def urls(self): return self.get_urls(), 'admin', self.name
<6> url()方法的扩展应用
from django.shortcuts import HttpResponse def test01(request): return HttpResponse("test01") def test02(request): return HttpResponse("test02") urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^yuan/', ([ url(r'^test01/', test01), url(r'^test02/', test02), ],None,None)), ]
扩展优化
from django.conf.urls import url,include from django.contrib import admin from django.shortcuts import HttpResponse def change_list_view(request): return HttpResponse("change_list_view") def add_view(request): return HttpResponse("add_view") def delete_view(request): return HttpResponse("delete_view") def change_view(request): return HttpResponse("change_view") def get_urls(): temp=[ url(r"^$".format(app_name,model_name),change_list_view), url(r"^add/$".format(app_name,model_name),add_view), url(r"^\d+/del/$".format(app_name,model_name),delete_view), url(r"^\d+/change/$".format(app_name,model_name),change_view), ] return temp url_list=[] for model_class,obj in admin.site._registry.items(): model_name=model_class._meta.model_name app_name=model_class._meta.app_label # temp=url(r"{0}/{1}/".format(app_name,model_name),(get_urls(),None,None)) temp=url(r"{0}/{1}/".format(app_name,model_name),include(get_urls())) url_list.append(temp) urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^yuan/', (url_list,None,None)), ]
仿admin的url路径分发
#############models.py########### from django.db import models class Book(models.Model): title = models.CharField(max_length=32) author = models.ForeignKey(to='Author') class Author(models.Model): name = models.CharField(max_length=32) #################admin.py########### from app01.models import * admin.site.register(Book) admin.site.register(Author) ##############views.py################ from django.shortcuts import HttpResponse def add(request): return HttpResponse('add') def change(request,id): return HttpResponse('change') def delete(request,id): return HttpResponse('delete') def show(request): return HttpResponse('show') ################url.py############## def get_urls2(): tmp = [] tmp.append(url(r'^add/',add)) tmp.append(url(r'^(\d+)/change/',change)) tmp.append(url(r'^(\d+)/delete/',delete)) tmp.append(url(r'^',show)) return tmp def get_urls(): temp = [] for model, admin_class_obj in admin.site._registry.items(): model_name = model._meta.model_name app_label = model._meta.app_label temp.append(url(r'^{}/{}/'.format(app_label,model_name),(get_urls2(),None,None))) #[url(r'^app01/book/',),] return temp urlpatterns = [ url(r'^admin/', (get_urls(), None, None)), url(r'^admin/', admin.site.urls), ]
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!