Maison > Article > développement back-end > Explication détaillée de l'utilisation et analyse du code source du composant admin de Django
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" ]django.contrib est un énorme ensemble de fonctionnalités pour les composants Django du code de base.
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), ]Une fois tout configuré, l'outil d'administration Django est prêt à fonctionner.
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)Cependant, cette méthode est relativement simple si vous souhaitez effectuer plus d'opérations de personnalisation, vous devez utiliser ModelAdmin pour fonctionner, comme : Méthode 1 :
class UserAdmin(admin.ModelAdmin): list_display = ('user', 'pwd',) admin.site.register(models.UserInfo, UserAdmin) # 第一个参数可以是列表Méthode 2 :
@admin.register(models.UserInfo) # 第一个参数可以是列表 class UserAdmin(admin.ModelAdmin): list_display = ('user', 'pwd',)ModelAdmin Fournit un grand nombre de fonctions personnalisables, telles que 1 list_display, lors du listing, personnalisez les colonnes affichées.
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): list_display = ('user', 'pwd', 'xxxxx') def xxxxx(self, obj): return "xxxxx"2. list_display_links, lors de la liste, vous pouvez cliquer pour accéder à la colonne personnalisée.
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): list_display = ('user', 'pwd', 'xxxxx') list_display_links = ('pwd',)3. list_filter, lors de la liste, personnalisez le filtre rapide sur le côté droit. 4. list_select_rated, lors de la création d'une liste, si la requête de jointure de table sélectionnera automatiquement_rated5. lors de la création d'une liste, les colonnes qui peuvent être modifiées .
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): list_display = ('user', 'pwd','ug',) list_editable = ('ug',)6. search_fields, dans la liste, fonction de recherche floue
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): search_fields = ('user', 'pwd')7. , lorsque dans la liste, pour la recherche Date et DateTime Type
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): date_hierarchy = 'ctime'8 inlines, page détaillée, s'il y a d'autres tables faisant FK avec la table actuelle, puis la page détaillée peut être ajoutée et supprimée dynamiquement
class UserInfoInline(admin.StackedInline): # TabularInline extra = 0 model = models.UserInfo class GroupAdminMode(admin.ModelAdmin): list_display = ('id', 'title',) inlines = [UserInfoInline, ]9 action, lors du listing, personnaliser l'opération dans l'action
@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 = True10 Modèle HTML personnalisé
add_form_template = None change_form_template = None change_list_template = None delete_confirmation_template = None delete_selected_confirmation_template = None object_history_template = None11 raw_id_fields, page détaillée, pour les champs FK et M2M devenir Formulaire de zone de saisie
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): raw_id_fields = ('FK字段', 'M2M字段',)12 champs, sur la page détaillée, les champs des champs affichés
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): fields = ('user',)13 exclure, Sur la page détaillée, champs exclus
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): exclude = ('user',)14 readonly_fields, sur la page détaillée, lire -champs uniquement
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): readonly_fields = ('user',)15 champs, sur la page détaillée, utilisez la balise champsets pour diviser et afficher les données
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): fieldsets = ( ('基本数据', { 'fields': ('user', 'pwd', 'ctime',) }), ('其他', { 'classes': ('collapse', 'wide', 'extrapretty'), # 'collapse','wide', 'extrapretty' 'fields': ('user', 'pwd'), }), )16 sur la page détaillée, Lorsque M2M est affiché, sélection du mouvement des données (direction : haut, bas et gauche et droite)
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): filter_vertical = ("m2m字段",) # 或filter_horizontal = ("m2m字段",)17 commande, lors du listing, règle de tri des données
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): ordering = ('-id',) 或 def get_ordering(self, request): return ['-id', ]18. l'option d'affichage radio (FK utilise select par défaut)
radio_fields = {"ug": admin.VERTICAL} # 或admin.HORIZONTAL19 form = ModelForm, utilisé pour personnaliser la validation du formulaire lorsque l'utilisateur le demande
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 = MyForm20 empty_value_display = "Lorsque les données de la colonne sont vides, affichez la valeur par défaut "
@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执行流程
f35d6e602fd7d0f0edfa6f7d103c1b57 循环加载执行所有已经注册的app中的admin.py文件
def autodiscover(): autodiscover_modules('admin', register_to=site)
2cc198a1d5eb0d3eb508d858c9f5cbdb 执行代码
#admin.py class BookAdmin(admin.ModelAdmin): list_display = ("title",'publishDate', 'price') admin.site.register(Book, BookAdmin) admin.site.register(Publish)
5bdf4c78156c7953567bb5a0aef2fc53 admin.site
这里应用的是一个单例模式,对于AdminSite类的一个单例模式,执行的每一个app中的每一个admin.site都是一个对象
23889872c2e8594e0f446a471a78ec4c 执行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)
到这里,注册结束!
43ad812d3a971134e40facaca816c822 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
efbfa0de8737dc86eae413541a49df20 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!