Heim >Backend-Entwicklung >Python-Tutorial >Detaillierte Erläuterung der Verwendung und Quellcode-Analyse der Admin-Komponente von Django
Dieser Artikel stellt hauptsächlich die Verwendung und Quellcode-Analyse der Admin-Komponente von Django vor. Jetzt kann ich ihn mit Ihnen teilen
admin-Komponente Mit
Django bietet webbasierte Verwaltungstools.
Djangos automatisierte Verwaltungstools sind Teil von django.contrib. Sie können es in INSTALLED_APPS in der Datei „settings.py“ des Projekts sehen:
# 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 ist ein riesiger Funktionssatz, der aus den Django-Basiscodekomponenten besteht.
Aktivierungsverwaltungstool
Normalerweise legen wir es automatisch in urls.py fest, wenn wir das Projekt generieren,
from django.conf.urls import url from django.contrib import admin urlpatterns = [ url(r'^admin/', admin.site.urls), ]
Sobald dies alles konfiguriert ist, ist das Django-Administrationstool betriebsbereit.
Verwenden Sie das Verwaltungstool
Starten Sie den Entwicklungsserver und besuchen Sie dann http://127.0.0.1:8000/admin/ im Browser, um die Anmeldeschnittstelle zu erhalten Sie können einen Superuser über den Befehl python manage.py createsuperuser erstellen.
Damit die Admin-Oberfläche ein bestimmtes Datenmodell verwalten kann, müssen wir das Datenmodell zunächst beim Admin registrieren
from 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
Admin-Anpassung
In admin.py müssen Sie nur eine bestimmte Klasse im Modus registrieren, um die Funktionen zum Hinzufügen, Löschen, Ändern und Einchecken im Admin zu implementieren, wie zum Beispiel:
admin.site.register(models.UserInfo)
Diese Methode ist jedoch relativ einfach. Wenn Sie weitere Anpassungsvorgänge durchführen möchten, müssen Sie ModelAdmin verwenden, z. B.:
Methode 1:
class UserAdmin(admin.ModelAdmin): list_display = ('user', 'pwd',) admin.site.register(models.UserInfo, UserAdmin) # 第一个参数可以是列表
Methode 2:
@admin.register(models.UserInfo) # 第一个参数可以是列表 class UserAdmin(admin.ModelAdmin): list_display = ('user', 'pwd',)
ModelAdmin Bietet eine große Anzahl anpassbarer Funktionen, z. B.
1. Passen Sie beim Auflisten die angezeigten Spalten an.
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): list_display = ('user', 'pwd', 'xxxxx') def xxxxx(self, obj): return "xxxxx"
2. list_display_links, beim Auflisten können Sie auf klicken, um zur benutzerdefinierten Spalte zu springen.
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): list_display = ('user', 'pwd', 'xxxxx') list_display_links = ('pwd',)
3. Passen Sie beim Auflisten den Schnellfilter auf der rechten Seite an.
4. list_select_related, ob die Join-Tabellenabfrage automatisch ausgewählt wird
5. list_editable, wenn eine Liste bearbeitet werden kann
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): list_display = ('user', 'pwd','ug',) list_editable = ('ug',)
6. Suchfelder, Fuzzy-Suchfunktion in der Liste
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): search_fields = ('user', 'pwd')
7. Suche nach Datum und Datum/Uhrzeit Typen in Liste
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): date_hierarchy = 'ctime'
8 Inlines, Detailseite, wenn es andere Tabellen gibt, die FK mit der aktuellen Tabelle ausführen, dann kann die Detailseite dynamisch hinzugefügt und gelöscht werden
class UserInfoInline(admin.StackedInline): # TabularInline extra = 0 model = models.UserInfo class GroupAdminMode(admin.ModelAdmin): list_display = ('id', 'title',) inlines = [UserInfoInline, ]
9 Aktion, passen Sie beim Auflisten den Vorgang in der Aktion an
@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
10 HTML-Vorlage anpassen
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
11 raw_id_fields, detaillierte Seite, für FK- und M2M-Felder werden zum Eingabefeldformular
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): raw_id_fields = ('FK字段', 'M2M字段',)
12 Felder, auf der Detailseite die Felder der angezeigten Felder
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): fields = ('user',)
13 ausschließen, auf der Detailseite die Ausgeschlossenen Felder
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): exclude = ('user',)
14 readonly_fields, für Detailseiten, schreibgeschützte Felder
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): readonly_fields = ('user',)
15 Feldsätze, für detaillierte Seiten verwenden Sie Feldsatz-Tags. Daten werden geteilt und angezeigt
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): fieldsets = ( ('基本数据', { 'fields': ('user', 'pwd', 'ctime',) }), ('其他', { 'classes': ('collapse', 'wide', 'extrapretty'), # 'collapse','wide', 'extrapretty' 'fields': ('user', 'pwd'), }), )
16 Bei der Anzeige der Detailseite, M2M, Datenbewegungsauswahl (Richtung: nach oben). , unten und links und rechts)
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): filter_vertical = ("m2m字段",) # 或filter_horizontal = ("m2m字段",)
17 Reihenfolge, beim Auflisten, Datensortierregeln
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): ordering = ('-id',) 或 def get_ordering(self, request): return ['-id', ]
18. radio_fields, verwenden Sie beim Anzeigen detaillierter Seiten Radiooptionen (FK verwendet standardmäßig „select“)
radio_fields = {"ug": admin.VERTICAL} # 或admin.HORIZONTAL
19 form = ModelForm, wird zum Anpassen verwendet Formularvalidierung bei Benutzeranfragen
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
20 empty_value_display = „Wenn die Spaltendaten leer sind, wird der Standardwert angezeigt“
@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)
Administrator-Quellcode-Analyse
Singleton-Muster
Singleton-Muster ist ein Der Hauptzweck dieses Musters besteht darin, sicherzustellen, dass nur eine Instanz einer Klasse vorhanden ist. Singleton-Objekte sind praktisch, wenn im gesamten System nur eine Instanz einer bestimmten Klasse angezeigt werden soll.
Zum Beispiel werden die Konfigurationsinformationen eines Serverprogramms in einer Datei gespeichert und der Client liest die Konfigurationsdateiinformationen über eine AppConfig-Klasse. Wenn der Inhalt der Konfigurationsdatei während der Ausführung des Programms an vielen Stellen verwendet werden muss, müssen also an vielen Stellen Instanzen des AppConfig-Objekts erstellt werden, was zur Existenz mehrerer AppConfig-Instanzobjekte führt im System, und dies führt zu einer erheblichen Speicherverschwendung, insbesondere wenn die Konfigurationsdatei viel Inhalt enthält. Tatsächlich hoffen wir für eine Klasse wie AppConfig, dass nur ein Instanzobjekt vorhanden ist, während das Programm ausgeführt wird.
In Python können wir verschiedene Methoden verwenden, um das Singleton-Muster zu implementieren:
Module verwenden
Verwenden Sie __new__
Verwenden Sie den Dekorator
Verwenden Sie die Metaklasse
(1 ) mit __new__
为了使类只能出现一个实例,我们可以使用 __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), ]
Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der Verwendung und Quellcode-Analyse der Admin-Komponente von Django. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!