Django

Django [관리자 페이지] 커스텀 페이지 추가하기

nyanguk 2021. 2. 3. 23:36

장고가 기본적으로 제공하는 관리자 페이지에 나만의 커스텀 페이지를 추가하려면 어떻게 해야할까?

일반 어플리케이션에서 했던 것과 동일하게 html파일을 만들고, views.py 에 구현하고, urls.py에 URL을 할당했다.

관리자 커스텀 페이지를 추가하는 것 또한 일반 어플리케이션과 비슷하지만 다른점을 가지고 있다.

 

이번 게시물에서는 관리자 커스텀 페이지를 추가 해보도록 한다.

 

관리자 페이지 추가하기

관리자 페이지 복사하기 

시작하기 앞서 admin의 html은 현재 나의 프로젝트에서는 찾아볼 수 없다. 그러므로 가장 먼저 관리자 페이지의 html파일을 찾아만 한다.

터미널 창에 아래와 같은 명령어를 입력하면 주소가 나오고 해당 디렉토리에서 

/Django/Custom_admin/my/lib/python3.7/site-packages/django/contrib/admin/templates 로 들어가게 되면 admin의 base_site.html 를 찾을 수 있다.

# python -c "import django; print(django.__path__)"

 

 

템플릿 디렉토리 생성하기

프로젝트 디렉토리 안에 templates 디렉토리를 ,templates 디렉토리안에 admin 디렉토리를 만든 뒤 위의 base_site.html을 복사하자

<!-- Custom_admin/templates/admin/base_site.html
{% extends "admin/base.html" %}

{% block title %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %}

{% block branding %}
<h1 id="site-name"><a href="{% url 'admin:index' %}">{{ site_header|default:_('Django administration') }}</a></h1>
{% endblock %}

{% block nav-global %}{% endblock %}
-->

 

내 프로젝트의 settings.py에서 'DIRS' 를 아래와 같이 수정해준다. 

#TEMPLATES = [
#    {
#        'BACKEND': 'django.template.backends.django.DjangoTemplates',
#        'DIRS': [BASE_DIR / 'templates'],
#        'APP_DIRS': True,
#        'OPTIONS': {
#            'context_processors': [
#                'django.template.context_processors.debug',
#                'django.template.context_processors.request',
#                'django.contrib.auth.context_processors.auth',
#                'django.contrib.messages.context_processors.messages',
#            ],
#        },
#    },
#]

 

추가할 관리자 페이지의  html 작성하기 

모든 post들을 나열하는 관리자 페이지를 추가 하고자 한다.

admin 의 모든 html은 다음과 같은 경로에 존재한다. my/lib/python3.7/site-packages/django/contrib/admin/templates

이때 my는 내 프로젝트와 동등한 위치에있는 가상환경 구축시 생기는 디렉토리이다. (my)가 나의 가상환경 이름

관리자 페이지의 추가를 위해서는 우리가 항상 작업하던 공간이 (그래서 from django.contib import ~ 등으로 불러 온것 이다. )아닌 직접 admin 이 있는 곳으로가서 html을 추가 해줘야한다.

 

<!--my/lib/python3.7/site-packages/django/contrib/admin/templates/admin/post_status.html--> 
{% extends "admin/base_site.html" %}
{% block content %}
    <h2>Post Status</h2>
    <ul>
        {% for post in posts %}
            <li>{{ post.title }}</li>
        {% endfor %}
    </ul>
{% endblock %}

 

뷰와 url 추가하기 

 

어플리케이션에서 새로운 페이지를 추가 할때마다 html, view , url을 생성 해줘야 함을 알고 있다. 마찬가지로 새로운 페이지를 추가하는 것이기 때문에 view,url을 생성한다.

어플리케이션과 다른점은 views.py와 urls.py를 구분하여 적지 않고 admin.ModelAdmin 을 받는 클래스 안에 모두 적어준다.

admin.py를 열어 PostAdmin 클래스 안에 아래 내용을 추가하자 물론 필요한 모듈을 불러 오는 것도 잊지 말자!

from django.urls import path
from django.template.response import TemplateResponse
# Register your models here.
class PostAdmin(admin.ModelAdmin):
	...
    def get_urls(self):
        urls = super().get_urls()
        post_urls = [
            path(r'status/', self.admin_site.admin_view(self.post_status_view))
        ]
        return post_urls + urls
    def post_status_view(self, request):
        context = dict(
            self.admin_site.each_context(request),
            posts=Post.objects.all(),
        )
        return TemplateResponse(request, "admin/post_status.html", context)

메소드 get_urls()

메소드  get_urls() 는 admin의 url을 얻어오고 추가될 페이지의 url을 더해주는 역할 이다. admin의 url부분이 공통이기 때문에 이렇게 할 수 있다. 

path를 통해 해당 url을 어떤 뷰와 연결 시킬지 설정해준다. 특히 어플리케이션과 다른점은 같은 class안에 메소드로 뷰를 구현하는 것이다. (사실 뷰와  url이 많아졌을때 구분하려고 veiws.py랑 urls.py랑 나누는 것인데 만약 커스텀 admin페이지가 많아진다면 분히 해야할 것이다.)

 

self.메소드 VS self.admin_site.admin_view(self.메소드)

self.post_status_viewself.admin_site.admin_view(self.post_status_view)으로 post_status_view 메소드를 부를 수 있다. 하지만 두개는 분명한 차이가 존재한다.

self.post_status_view는 어떠한 허가도 체크 하지 않아 모든 사람이 접근할 수 있다는 보안 문제가 발생한다.

또한 캐싱을 방지하는 세부정보를 제공하지 않으며 이로 인해 페이지가 *캐싱 미들웨어가 켜져 있을때)오래된 데이터를 띄울 수 있다는 문제가 있다.

 

그래서 장고는 유용한 wrapper인 AdminSite.admin_view()를 제공한다. 그러므로 AdminSite가 admin_site이므로 self.admin_site.admin_view(self.post_status_view)로 쓸 수 있는 것이다. 

 

 

메소드 post_status_view()

어플리케이션과 동일하게 context 라는 딕션어리를 전달하여 템플릿을 요청 한다.

참고문서

https://docs.djangoproject.com/ko/3.1/intro/tutorial07/

https://docs.djangoproject.com/en/3.1/ref/contrib/admin/