Seul Lee

Mathpresso 서버 개발자

Navigation
 » Home
 » Github
 » XML Feed

type을 이용한 동적 클래스 생성 및 Django admin 자동 등록

14 Mar 2019 » django



type을 이용한 동적 클래스 생성 및 Django admin 자동 등록


python에는 type이라는 함수(사실은 클래스)가 있는데, 주로 자료형을 확인하기 위해 사용되지만

type을 통해 클래스를 동적으로 생성할 수 있다.

사용법은 간단하다. 클래스의 이름, 상속 받을 클래스, 클래스의 바디를 구성할 값들을 넘겨 주면 된다.


type(classname, superclasses, attributes_dict)


Django를 사용하다보면 모델을 admin에 일일이 등록해줘야 하는 불편함이 있다.

이럴 경우 type을 이용하면 단순 admin에 등록이 필요한 모델의 경우 손쉽게 추가해줄 수 있다.


전체 예제 코드


# coding: utf-8
from django.contrib import admin
from django.contrib.admin.sites import AlreadyRegistered


 def get_list_display(model):
    return [field.attname for field in model._meta.fields]


 def get_raw_id_fields(model):
    return [field.name for field in model._meta.fields if field.remote_field]


 def auto_register(model):
    list_display = get_list_display(model)
    raw_id_fields = get_raw_id_fields(model)

    admin_class_name = f'{model._meta.object_name}Admin' 
    admin_model = type(admin_class_name, (admin.ModelAdmin, ), {
        'list_display': list_display, 
        'raw_id_fields': raw_id_fields})

    try:
        admin.site.register(model, admin_model)
    except AlreadyRegistered:
        pass 


list_display에 전체 필드를 추가하고, ForeignKey의 경우에는 raw_id_fields에 추가한 다음 admin 모델을 만들고 admin 페이지에 등록하는 함수이다.

type을 살펴보면 각 model의 이름에 Admin이라는 suffix를 붙인 이름을 첫 인자로 받으며, admin클래스가 되기 위해 상속 받을 모델인 admin.ModelAdmin을 두 번째 인자로 받는다. 마지막으로 각 admin 클래스의 list_display와 raw_id_fields가 될 값들을 인자로 받는다.


위의 코드를 실제로 사용할 때는 auto_register에 model 클래스를 넘겨주기만 하면 된다.


models = [
    'Blog',
    'Post',
    'Comment',
]

for model in models:
    auto_register(model)

그러면 BlogAdmin, PostAdmin, CommentAdmin이 자동으로 생성되어 admin에 등록된다.