Django에서 사용자 정의admin---Xadmin의 실현

25176 단어
Django 프레임워크에서 백엔드 관리 페이지인admin을 가지고 있습니다. 이 관리 페이지는 완전하지만 일부는 우리가 필요로 하는 것이 아니기 때문에 우리는admin의 실현 절차에 따라 자신의 수요를 사용자 정의할 수 있습니다. 즉,admin의 실현 방식에 따라 사용자 정의 - Xadmin을 실현할 수 있습니다.
먼저, 우리는 먼저 admin의 절차를 분석했다. Django에서 우리가 프로젝트를 만들 때 Django는 하나의admin URL을 가지고 서로 다른 모델표의 삭제와 수정을 실현했다. 그러면 admin은 어떻게 URL의 분배를 실현했는가?
우리는 세 부분에서 admin의 루트 분배 실현을 볼 수 있다
1, 시작
우리는 from django를 통과할 수 있다.contrib import admin 어떻게 시작하는지 보기
Django가 시작되면 관리자에서py 파일에 설정 파일 settings를 불러옵니다.py,settings.py에 INSTALLED 하나 있음APPS 이 설정 항목은 Django가 설정 항목의 내용에 따라 한 번에 모든 app를 불러옵니다.
# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'Xadmin.apps.XadminConfig',
    'blogs.apps.BlogsConfig',
    'bigs.apps.BigsConfig',
]

django에 로드contrib.admin 시, admin 관련 로드, 우리는 admin을 클릭하여 admin의 에 들어갑니다init__.py 파일,
from django.contrib.admin.sites import AdminSite, site
from django.utils.module_loading import autodiscover_modules

def autodiscover():
    autodiscover_modules('admin', register_to=site)

auto 실행discover 이 인터페이스는 모든 앱의admin을 자동으로 불러옵니다.py 이 파일, 이것은admin의 시작 파일입니다
2, 등록
모든 APP에서 admin을 자동으로 로드합니다.py 파일이 실행되었을 때, 모든admin을 한 번에 기록합니다.site.register(모형류)라는 방법의 모형류를 완성하여 모형류의 등록을 완성합니다.
모든 모델 클래스가admin을 실행합니다.site.register()이라는 방법으로 등록을 마쳤습니다. 그러면 이 방법 내부에 무엇을 했습니까?
우리는site를 눌러서 관리자의 원본에 들어갈 수 있다. 이를site=AdminSite()site는 하나의 대상이고 AdminSite와 같은 종류의 대상이며 하나의 단일 대상이다. 그러면 우리는register가 이 단일 대상의 방법이라는 것을 확신할 수 있다. 그러면 이 방법에서 도대체 무엇을 한 것일까?
class AdminSite(object):
    """
    An AdminSite object encapsulates an instance of the Django admin application, ready
    to be hooked in to your URLconf. Models are registered with the AdminSite using the
    register() method, and the get_urls() method can then be used to access Django view
    functions that present a full admin interface for the collection of registered
    models.
    """


    def __init__(self, name='admin'):
        self._registry = {}  # model_class class -> admin_class instance
        self.name = name
 

    #   register   

    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)

  #  :            
        

site 객체를 예로 들면 self. 가 생성됩니다.registry={} 이 대상 속성, 만약 우리가admin 을 지정하지 않았다면class, 그럼adminclass는 바로 Model Admin입니다. 이를 통해 알 수 있듯이adminclass는 관리자가 제공하는 맞춤형 페이지의 사용자 정의 클래스입니다. 이 클래스는 ModelAdmin 클래스를 계승해야 합니다. 다음은 다음과 같습니다.
class ModelAdmin(BaseModelAdmin):
    "Encapsulates all admin options and functionality for a given model."

    list_display = ('__str__',)
    list_display_links = ()
    list_filter = ()
    list_select_related = False
    list_per_page = 100
    list_max_show_all = 200
    list_editable = ()
    search_fields = ()
    date_hierarchy = None
    save_as = False
    save_as_continue = True
    save_on_top = False
    paginator = Paginator
    preserve_filters = True
    inlines = []

    # Custom templates (designed to be over-ridden in subclasses)
    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
    popup_response_template = None

    # Actions
    actions = []
    action_form = helpers.ActionForm
    actions_on_top = True
    actions_on_bottom = False
    actions_selection_counter = True
    checks_class = ModelAdminChecks

    def __init__(self, model, admin_site):
        self.model = model
        self.opts = model._meta
        self.admin_site = admin_site
        super(ModelAdmin, self).__init__()

    def __str__(self):
        return "%s.%s" % (self.model._meta.app_label, self.__class__.__name__)

그래서 맞춤형 스타일링이 있든 없든self.registry[model] = admin_class(모델,self), 즉 모델 클래스를 등록하면 대상의registry 이 사전에 키 값을 추가합니다. 이 키는 우리가 등록한 모델 모델입니다. 값은 모델 Admin의 스타일 클래스나 모델 Admin 클래스를 계승하는 대상입니다.
3, 디자인 url
사이트는 하나의 단일 대상이기 때문에 관리자는 모든 관리자를 실행합니다.py 파일을 사용하면 모든 등록 모델을 포함하는 전체 사전을 얻을 수 있습니다registry, 이self.registry (즉admin.site 대상) 사전은 이admin을 순환할 수 있습니다.site._registry 사전에서 이 키 값의 쌍을 얻으면 이 키 값의 쌍을 얻으면 무슨 소용이 있습니까?이것이 바로 관리자가 URL을 디자인할 때 사용할 수 있는 것이다.
우리가admin이라는 백엔드 관리 페이지를 방문하면 이 페이지가 우리가 등록한 모든 모델에 대해 추가 삭제 검사 기능을 실현할 수 있다. 각 기능 인터페이스가 서로 다른 모델 유형에 대응할 때 데이터가 다른 것을 제외하고 똑같다. 즉,admin은 서로 다른 모델 유형에 대해 하나의 URL, 하나의 템플릿을 사용한다. 그러면 이 URL은 어떻게 디자인된 것입니까?
각 모델 클래스의 네 가지 기능 페이지에 액세스하면 다음과 같은 규칙을 확인할 수 있습니다.
조회 페이지 URL:http://IP:PORT/admin/app이름/모델 클래스 이름 (모두 소문자)/
페이지 추가 url:http://IP:PORT/admin/app이름/모델 클래스 이름 (모든 소문자)/add
페이지 URL 편집하기http://IP:PORT/admin/app이름/모델 클래스 이름 (모든 소문자)/id 값/change
페이지 URL을 삭제하려면:http://IP:PORT/admin/app이름/모델 클래스의 이름 (모든 소문자)/id 값/delete
이 법칙을 통해 url 분배의 실현을 알 수 있다
그러나 이 실현 과정에서 우리가 주의해야 할 것이 하나 있을 때 사용자가 방문한 요청이 가지고 있는 경로는 문자열의 유형이고 우리는 Request를 통과할 수 있다.path는 사용자가 방문하는 경로를 얻을 수 있고 사용자가 방문하는 앱 아래의 모델 클래스도 얻을 수 있다. 그러나 이 두 파라미터는 모두 문자열의 유형이다. 어떻게 문자열을 통해 사용자가 방문하는 테이블을 얻을 수 있는지 이것은 번거롭다. 이때 우리는 importlib 모듈로 이런 종류를 얻을 수 있다고 생각할 수 있다. 그러나 이런 과정은 매우 번거롭다.Django는 우리에게 상응하는 방법을 봉인해 주었다. 우리는 이 모델 클래스의 클래스를 통해.meta.model_name 이 방법은 대응하는 문자열 형식의 클래스 이름을 얻을 수 있습니다. 마찬가지로 우리도 이 클래스 이름을 통과할 수 있습니다.meta.app_label은 문자열 형식의 해당하는 APP 이름을 받습니다
#   model        
model._meta.model_name   #          (    )

model._meta.app_label   #         APP       

#
model._meta.get_field(" ") # field_obj,
                            # : field_obj.verbose_name

이 두 가지 포장 방법 을 통해 우리 의 골치 아픈 문제 를 완벽하게 해결하였다
from django.conf.urls import url

from django.contrib import admin

def get_urls_operate():
    emp = []
    emp.append(url(r'^$',         ))
    emp.append(url(r'^add/$',         ))
    emp.append(url(r'^(\d+)/change/$',         ))
    emp.append(url(r'^(\d+)/delete/$',         ))
    return emp


def get_urls():
    temp = []
    for model,main_class_obj in admin.site._registry.items():
        app_name = model._meta.app_label
        model_name = model._meta.model_name
        temp.append(url(r'^{}/{}/'.format(app_name,model_name),(get_urls_operate(),None,None)))   #          
    return temp

urlpatterns = [
     url(r'^Xadmin/',(get_urls(),None,None))     #                   
]

이렇게 하면 우리는 하나의 경로를 통해 서로 다른 장면의 분배를 실현할 수 있다
이 세 부분을 통해 우리는 admin의 실현 방식에 따라 맞춤형 Xadmin에서
우리는 관리자 내부의 실현 절차를 이해했고 이 실현 과정을 하나의 유형에 봉인할 수 있다.
저희가 Xadmin을 맞춤형으로 제작할 때도admin의 절차에 따라 실현해야 합니다. 우선은 시작 항목입니다.admin에서Django가 시작할 때 모든 app에서의admin을 자동으로 실행합니다.py 파일은 시작할 때 app 아래의 모든 사용자 정의를 자동으로 실행할 수 있습니다.py 파일, 예를 들어 Xadmin.py 파일, Django가 시작될 때 사용자 정의 Xadmin을 불러오는 방법을 자동으로 스캔합니다.py 파일은요?이게 문제야.
Django가 시작할 때 설정 파일 settings를 불러오는 것을 관찰할 수 있습니다.py,settings.py 파일의 INSTALLEDAPPS 이 목록, 이 목록에는 Django 프로젝트에 있는 모든 앱의 설정 정보가 놓여 있습니다. 우리는 이 목록을 관찰합니다. 우리가 직접 연 앱은 설정 정보를 설정할 때 앱 이름 뒤에 하나를 추가합니다.apps.(app명 이니셜 대문자)Config라는 물건은 저희 앱에 대응하는 Django가 자동으로 앱을 설정합니다.py 파일, 그럼 이 apps.py 파일이 무슨 역할을 할까요, 이 앱을 엽니다.py 파일, 안에 있는 설정 정보를 보십시오:
블로그라는 앱을 예로 들면 다음과 같다.
from django.apps import AppConfig


class BlogsConfig(AppConfig):
    name = 'blogs'

우리는 안에 하나의 클래스가 정의되어 있음을 알 수 있다. 이 클래스의 클래스 이름은 settings 설정 정보에서 apps 뒤에 있는 동동이다. 이 클래스 중의 정적 속성name은 현재의 앱 이름이고 이 클래스는 AppConfig이라는 클래스를 계승한다.이것이 바로 우리가 여기에서py 파일에서 얻을 수 있는 모든 것을 언뜻 보면 쓸모 있는 정보가 없다. 그러면 우리는 그것이 계승하는 클래스에서 찾을 수밖에 없다.
MODELS_MODULE_NAME = 'models'


class AppConfig(object):
    """
    Class representing a Django application and its configuration.
    """

    def __init__(self, app_name, app_module):
        # Full Python path to the application eg. 'django.contrib.admin'.
        self.name = app_name

    def ready(self):
        """
        Override this method in subclasses to run code when Django starts.
    # : , Django
"""

전체 AppConfig를 보면 우리가 시작할 코드를 다시 쓰는 Ready 방법에 놓으면 됩니다
from django.apps import AppConfig
from django.utils.module_loading import autodiscover_modules


class XadminConfig(AppConfig):
    name = 'Xadmin'
    def ready(self):
        autodiscover_modules('Xadmin')   #Django          app  Xadmin.py  

이렇게 하면 우리는 자체 맞춤형 Xadmin의 시작 단계를 완성했고 시작한 후에 우리는 다음 단계의 등록을 진행할 것이다
모든 앱에 있는 Xadmin.py 파일에 등록된 모델
Blogs라는 APP의 UserInfo, Book을 예로 들면 다음과 같습니다.
from blogs import models
from Xadmin.service.Xadmin import site

site.register(models.UserInfo)
site.register(models.Book)

다음은 URL을 디자인한 것입니다. 우리는 관리자 방식을 본떠서 단일 대상인 관리자를 만들 수 있습니다.site의 이런 종류에 이런 방법을 봉합하세요.
from django.conf.urls import url
from django.shortcuts import HttpResponse,render

class ModelXadmin(object):
    def __init__(self,model,site):
        self.model = model
        self.site = site

    def show(self,request):
        data_list = self.model.objects.all()
        return render(request,'show.html',locals())  #locals()                == {"data_list":data_list}

    def add(self,request):
        return HttpResponse('    ')

    def edit(self,request, pk):
        return HttpResponse('    ')

    def delete(self,request, pk):
        return HttpResponse('    ')
    
    @property
    def get_urls_operate(self):
        emp = []
        emp.append(url(r'^$', self.show))
        emp.append(url(r'^add/$', self.add))
        emp.append(url(r'^(\d+)/change/$', self.edit))
        emp.append(url(r'^(\d+)/delete/$', self.delete))
        return emp
    
    @property
    def urls(self):
        return self.get_urls_operate,None,None


class XadminSite(object):
    def __init__(self,name='xadmin'):
        self._registry = {}
        
    def register(self,model,class_main=None,**option):
        if not class_main:
            class_main = ModelXadmin
        self._registry[model] = class_main(model,self)

    @property
    def get_urls(self):
        # print(admin.site._registry)
        temp = []
        for model, model_admin_object in self._registry.items():
            model_name = model._meta.model_name
            model_app = model._meta.app_label
            temp.append(url(r'^{}/{}/'.format(model_app, model_name), model_admin_object.urls))
        return temp

    @property
    def urls(self):
        return self.get_urls,None,None


site = XadminSite()

 
비고: 관건은 왜 2층 분배를 Model Xadmin 클래스에 설정했는지 하는 것이다. 이것은 분명히 이 클래스에 놓으면 좋은 점이 있을 것이다. 만약에 우리가 이 2급 분배를 Xadmin Site에 두면 우리는 모든 모델의 데이터를 얻는 것이 매우 번거롭다. 그러나 만약에 우리가 이것을 Model Xadmin에 놓으면register(등록)할 때classadmin(Xadmin Site)은 모든 모델 클래스를 전달하기 때문에 이 클래스에 놓으면 우리는self를 통과할 수 있다.모델이라는 속성은 모든 모델 클래스의 데이터 (self.모델.objects.all () 를 얻어서 이 모델 테이블을 쉽게 얻을 수 있습니다.

좋은 웹페이지 즐겨찾기