Django Admin 커스텀 Deep Dive

GisangLee·2023년 7월 11일
0

django

목록 보기
34/35

Django Admin은 Model에 의존성이 강해서 모델없이 어드민 view를 추가하거나 기존 admin 모듈에 내 view를 추가하는 방법을 찾았다.
나의 요구사항은 아래와 같았다.

  • 확장성 가능해야함.
  • admin.site.urls에 내 admin view의 path가 자동으로 등록돼야함.
  • model 없이 django.contrib.admin의 templates를 상속받아 사용해야 한다.

1. AdminSite Override

  • project/admin/admin.py
from django.contrib.admin import AdminSite as DjangoAdminSite
....
....

class AdminSite(DjangoAdminSite):
    site_header = (
        mark_safe(f'<img src="{settings.STATIC_URL + settings.SITE_LOGO}" height="28" style="vertical-align: bottom;" />')
        if settings.SITE_LOGO
        else f"{settings.SITE_NAME} 어드민"
    )
    site_url = settings.FRONTEND_URL

    def get_urls(self):
        def wrap(view, cacheable=False):
            def wrapper(*args, **kwargs):
                return self.admin_view(view, cacheable)(*args, **kwargs)

            wrapper.admin_site = self
            return update_wrapper(wrapper, view)

        urls = [
            path("myview", wrap(self.my_view), name="myview"),
        ]
        urls += super().get_urls()
        return urls
        
    def my_view(self, request, *args, **kwargs):
        context = dict(super().each_context(request))
        return TemplateResponse(request, "admin/my_view/test.html", context)

Django의 AdminSite 코드를 들여다보니 wrap 데코레이터 function이 admin의 view authentication 역할을 하는 것으로 보여짐.


  • project/templates/admin/my_view/test.html
{% extends "admin/base_site.html" %}
{% load i18n admin_urls static admin_list %}
{% load static %}

{% block extrastyle %}
  {{ block.super }}
  <link rel="stylesheet" href="{% static "admin/css/changelists.css" %}">
  {% if cl.formset %}
    <link rel="stylesheet" href="{% static "admin/css/forms.css" %}">
  {% endif %}
  {% if cl.formset or action_form %}
    <script src="{% url 'admin:jsi18n' %}"></script>
  {% endif %}
  {{ media.css }}
  {% if not actions_on_top and not actions_on_bottom %}
    <style>
      나만의 css 작성
    </style>
  {% endif %}
{% endblock %}

{% block extrahead %}
{{ block.super }}
<title>하이</title>
<link href='https://fonts.googleapis.com/css?family=Roboto:400,100,300,700' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.4.0/axios.min.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.10.7/dayjs.min.js"></script>
{% endblock %}

{% block bodyclass %}
{{ block.super }}
{% endblock %}


{% if not is_popup %}
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'admin:index' %}">{% translate 'Home' %}</a>
&rsaquo; test
</div>
{% endblock %}
{% endif %}

{% block content %}
<div class="content">
  하이
</div>
<script>
</script>
{% endblock %}

  • project/admin/apps.py
from django.contrib.admin.apps import AdminConfig as DjangoAdminConfig


class AdminConfig(DjangoAdminConfig):
    default_site = "admin.admin.AdminSite"

get_urls에 path를 등록하고 view를 작성한 이후 템플릿을 만들어주면 끝

profile
포폴 및 이력서 : https://gisanglee.github.io/web-porfolio/

0개의 댓글