Detaillierte Erläuterung der Verwendung und Quellcode-Analyse der Admin-Komponente von Django

不言
Freigeben: 2018-05-04 14:26:59
Original
1700 Leute haben es durchsucht

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"
]
Nach dem Login kopieren

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),

]
Nach dem Login kopieren

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
Nach dem Login kopieren

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)
Nach dem Login kopieren

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) # 第一个参数可以是列表
Nach dem Login kopieren

Methode 2:

@admin.register(models.UserInfo)        # 第一个参数可以是列表
class UserAdmin(admin.ModelAdmin):
  list_display = ('user', 'pwd',)
Nach dem Login kopieren

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"
Nach dem Login kopieren

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',)
Nach dem Login kopieren

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',)
Nach dem Login kopieren

6. Suchfelder, Fuzzy-Suchfunktion in der Liste

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
  search_fields = ('user', 'pwd')
Nach dem Login kopieren

7. Suche nach Datum und Datum/Uhrzeit Typen in Liste

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
  date_hierarchy = 'ctime'
Nach dem Login kopieren

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, ]
Nach dem Login kopieren

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
Nach dem Login kopieren

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
Nach dem Login kopieren

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字段',)
Nach dem Login kopieren

12 Felder, auf der Detailseite die Felder der angezeigten Felder

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
  fields = ('user',)
Nach dem Login kopieren

13 ausschließen, auf der Detailseite die Ausgeschlossenen Felder

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
  exclude = ('user',)
Nach dem Login kopieren

14 readonly_fields, für Detailseiten, schreibgeschützte Felder

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
  readonly_fields = ('user',)
Nach dem Login kopieren

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'),
    }),
  )
Nach dem Login kopieren

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字段",)
Nach dem Login kopieren

17 Reihenfolge, beim Auflisten, Datensortierregeln

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
  ordering = ('-id',)
  或
  def get_ordering(self, request):
    return ['-id', ]
Nach dem Login kopieren

18. radio_fields, verwenden Sie beim Anzeigen detaillierter Seiten Radiooptionen (FK verwendet standardmäßig „select“)

radio_fields = {"ug": admin.VERTICAL} # 或admin.HORIZONTAL
Nach dem Login kopieren

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
Nach dem Login kopieren

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 = "指定列数据为空时,默认显示"
Nach dem Login kopieren

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)
Nach dem Login kopieren

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:

  1. Module verwenden

  2. Verwenden Sie __new__

  3. Verwenden Sie den Dekorator

  4. 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
Nach dem Login kopieren

在上面的代码中,我们将类的实例和一个类变量 _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()
Nach dem Login kopieren

将上面的代码保存在文件 mysingleton.py 中,然后这样使用:

from mysingleton import my_singleton
my_singleton.foo()
Nach dem Login kopieren

admin执行流程

<1> 循环加载执行所有已经注册的app中的admin.py文件

def autodiscover():
  autodiscover_modules(&#39;admin&#39;, register_to=site)
Nach dem Login kopieren

<2> 执行代码

#admin.py
class BookAdmin(admin.ModelAdmin):
  list_display = ("title",&#39;publishDate&#39;, &#39;price&#39;)

admin.site.register(Book, BookAdmin) 
admin.site.register(Publish)
Nach dem Login kopieren

<3> admin.site

这里应用的是一个单例模式,对于AdminSite类的一个单例模式,执行的每一个app中的每一个admin.site都是一个对象

<4> 执行register方法

admin.site.register(Book, BookAdmin) 
admin.site.register(Publish)
Nach dem Login kopieren

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)
Nach dem Login kopieren

到这里,注册结束!

<5> admin的URL配置

urlpatterns = [
  url(r&#39;^admin/&#39;, admin.site.urls),
]
Nach dem Login kopieren

class AdminSite(object):  
   def get_urls(self):
    from django.conf.urls import url, include   
    urlpatterns = []
    # Add in each model&#39;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&#39;^%s/%s/&#39; % (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(), &#39;admin&#39;, self.name
Nach dem Login kopieren

<6> url()方法的扩展应用

from django.shortcuts import HttpResponse
def test01(request):
  return HttpResponse("test01")

def test02(request):
  return HttpResponse("test02")

urlpatterns = [
  url(r&#39;^admin/&#39;, admin.site.urls),
  url(r&#39;^yuan/&#39;, ([
          url(r&#39;^test01/&#39;, test01),
          url(r&#39;^test02/&#39;, test02),

          ],None,None)),

]
Nach dem Login kopieren

扩展优化

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&#39;^admin/&#39;, admin.site.urls),
  url(r&#39;^yuan/&#39;, (url_list,None,None)),
]
Nach dem Login kopieren

仿admin的url路径分发

#############models.py###########
from django.db import models
class Book(models.Model):
  title = models.CharField(max_length=32)
  author = models.ForeignKey(to=&#39;Author&#39;)
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(&#39;add&#39;)
def change(request,id):
  return HttpResponse(&#39;change&#39;)
def delete(request,id):
  return HttpResponse(&#39;delete&#39;)
def show(request):
  return HttpResponse(&#39;show&#39;)
################url.py##############
def get_urls2():
  tmp = []
  tmp.append(url(r&#39;^add/&#39;,add))
  tmp.append(url(r&#39;^(\d+)/change/&#39;,change))
  tmp.append(url(r&#39;^(\d+)/delete/&#39;,delete))
  tmp.append(url(r&#39;^&#39;,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&#39;^{}/{}/&#39;.format(app_label,model_name),(get_urls2(),None,None))) #[url(r&#39;^app01/book/&#39;,),]
  return temp

urlpatterns = [
  url(r&#39;^admin/&#39;, (get_urls(), None, None)),
  url(r&#39;^admin/&#39;, admin.site.urls),
]
Nach dem Login kopieren

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!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage