>  기사  >  백엔드 개발  >  Django 관리 컴포넌트의 사용법과 소스코드 분석에 대한 자세한 설명

Django 관리 컴포넌트의 사용법과 소스코드 분석에 대한 자세한 설명

不言
不言원래의
2018-05-04 14:26:591694검색

이 글은 주로 Django의 관리 컴포넌트의 사용법과 소스 코드 분석을 자세하게 소개하고 있습니다. 이제는 필요한 친구들이 참고할 수 있도록 공유하겠습니다.

관리 컴포넌트 사용법

Django는 웹용 관리 도구를 기반으로 제공합니다.

Django 자동화 관리 도구는 django.contrib의 일부입니다. 프로젝트 settings.py의 INSTALLED_APPS에서 볼 수 있습니다.

# 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는 Django 코드 베이스의 필수적인 부분인 거대한 기능 세트입니다.

관리 도구 활성화

보통 프로젝트 생성 시 urls.py에 자동으로 설정해 주는데,

from django.conf.urls import url
from django.contrib import admin

urlpatterns = [
  url(r'^admin/', admin.site.urls),

]

이 모든 것이 구성되면 Django 관리 도구를 실행할 수 있습니다.

관리 도구

를 사용하여 개발 서버를 시작한 다음 브라우저에서 http://127.0.0.1:8000/admin/을 방문하여 로그인 인터페이스를 얻을 수 있습니다. Python 명령을 통해 슈퍼 사용자를 생성할 수 있습니다. manage.py는 슈퍼유저를 생성합니다.

관리 인터페이스에서 특정 데이터 모델을 관리하려면 먼저 해당 데이터 모델을 관리자에게 등록해야 합니다

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.py에서는 Mode의 특정 클래스에서는 다음과 같이 Admin에서 추가, 삭제, 수정 및 확인 기능을 구현할 수 있습니다.

admin.site.register(models.UserInfo)

그러나 이 방법은 비교적 간단합니다. 더 많은 사용자 정의 작업을 수행하려면 다음이 필요합니다. ModelAdmin을 사용하여 다음과 같이 작동합니다.

방법 1:

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

방법 2:

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

ModelAdmin은

1과 같은 다양한 사용자 정의 가능한 기능을 제공합니다. 나열할 때 표시되는 열을 사용자 정의합니다.

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
  list_display = ('user', 'pwd', 'xxxxx')
 
  def xxxxx(self, obj):
    return "xxxxx"

2. list_display_links, 나열 시 맞춤 열을 클릭하여 이동할 수 있습니다.

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
  list_display = ('user', 'pwd', 'xxxxx')
  list_display_links = ('pwd',)

3. list_filter 등록 시 오른쪽에 있는 퀵필터를 맞춤설정하세요.

4. list_select_관련, 리스트 생성 시 연결된 테이블 쿼리가 자동으로 선택되는지 여부

5. list_editable, 리스트 생성 시 편집 가능한 열

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
  list_display = ('user', 'pwd','ug',)
  list_editable = ('ug',)

6. 목록, 퍼지 검색 기능

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

7. date_hierarchy, 나열 시 Date 및 DateTime 유형 검색

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

8 인라인, 상세 페이지, 현재 테이블과 함께 FK된 다른 테이블이 있는 경우 , 그러면 세부 페이지를 동적으로 추가 및 삭제할 수 있습니다

class UserInfoInline(admin.StackedInline): # TabularInline
  extra = 0
  model = models.UserInfo
 
class GroupAdminMode(admin.ModelAdmin):
  list_display = ('id', 'title',)
  inlines = [UserInfoInline, ]

9 액션을 나열할 때 액션의 작업을 사용자 정의

@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 템플릿 사용자 정의

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 , 상세 페이지에서는 FK 및 M2M 필드가 입력 상자 형태가 됩니다.

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
  raw_id_fields = ('FK字段', 'M2M字段',)

12개 필드, 상세 페이지에서는 표시된 필드의 필드

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

13 제외, 상세 페이지에서는 제외된 필드

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

14 readonly_fields, 상세 페이지에서 읽기 전용 필드

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

15 ​​​​fieldsets, 상세 페이지에서 fieldset 태그를 사용하여 데이터를 분할하고 표시합니다

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
  fieldsets = (
    ('基本数据', {
      'fields': ('user', 'pwd', 'ctime',)
    }),
    ('其他', {
      'classes': ('collapse', 'wide', 'extrapretty'), # 'collapse','wide', 'extrapretty'
      'fields': ('user', 'pwd'),
    }),
  )

16 상세페이지에서 M2M이 표시되면 데이터 이동 선택(방향: 상하좌우)

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
  filter_vertical = ("m2m字段",) # 或filter_horizontal = ("m2m字段",)

17 순서, 나열시 데이터 정렬 규칙

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

18. radio_fields, 세부 정보 페이지에서 라디오 표시 옵션 사용(FK는 기본적으로 선택 사용)

radio_fields = {"ug": admin.VERTICAL} # 或admin.HORIZONTAL

19 form = ModelForm, 사용자 요청 시 양식 유효성 검사를 사용자 정의하는 데 사용됨

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 = "열 데이터가 비어 있으면 기본값을 표시합니다"

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

admin 소스 코드 분석

Singleton Pattern

Singleton Pattern은 일반적으로 사용되는 소프트웨어 디자인 패턴입니다. 이 패턴의 목적은 특정 클래스의 인스턴스가 하나만 존재하도록 하는 것입니다. 싱글톤 개체는 특정 클래스의 인스턴스 하나만 전체 시스템에 나타나도록 하려는 경우 유용합니다.

예를 들어 서버 프로그램의 구성 정보는 파일에 저장되며 클라이언트는 AppConfig 클래스를 통해 구성 파일 정보를 읽습니다. 프로그램을 실행하는 동안 구성 파일의 내용을 여러 위치에서 사용해야 하는 경우, 즉 AppConfig 개체의 인스턴스를 여러 위치에서 생성해야 하는 경우 여러 AppConfig 인스턴스가 존재하게 됩니다. 특히 구성 파일에 많은 콘텐츠가 포함된 경우 메모리가 심각하게 낭비됩니다. 실제로 AppConfig와 같은 클래스의 경우 프로그램이 실행되는 동안 인스턴스 개체가 하나만 존재하기를 바랍니다. ㅋㅋㅋ ) __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),
]

위 내용은 Django 관리 컴포넌트의 사용법과 소스코드 분석에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.