[Django] admin edit view에 테이블을 추가하고 싶을땐?
django admin 작업 중, order(주문) 모델의 change view에서 해당 주문에 포함되어 있는 상품을 테이블 형태로 출력하고 싶었습니다.
찾아본 바로는, 다음 2가지 방법으로 원하는 바를 이룰 수 있었습니다.
1. 새로운 view를 만들어, 각 주문마다 링크를 만들어 해당 링크로 접속 시에, 테이블 형태로 상품 정보를 출력하는 방법
2. change_form_template을 커스텀 하는 방법
첫번째 방법을 시도하다가, 생각대로 되지 않아 두번째 방법으로 이를 해결하였습니다. 해결 방법은 아래와 같습니다.
Order(주문) change view에서 해당 테이블을 보려고 하기 때문에, change_form_template을 override 해주었습니다. django에 기본적으로 정의되어 있는 change_form_template.html은 아래와 같습니다.
{% extends "admin/base_site.html" %}
{% load i18n admin_urls static admin_modify %}
{% block extrahead %}{{ block.super }}
<script src="{% url 'admin:jsi18n' %}"></script>
{{ media }}
{% endblock %}
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/forms.css" %}">{% endblock %}
{% block coltype %}colM{% endblock %}
{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} change-form{% endblock %}
{% if not is_popup %}
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'admin:index' %}">{% translate 'Home' %}</a>
› <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a>
› {% if has_view_permission %}<a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst }}</a>{% else %}{{ opts.verbose_name_plural|capfirst }}{% endif %}
› {% if add %}{% blocktranslate with name=opts.verbose_name %}Add {{ name }}{% endblocktranslate %}{% else %}{{ original|truncatewords:"18" }}{% endif %}
</div>
{% endblock %}
{% endif %}
{% block content %}<div id="content-main">
{% block object-tools %}
{% if change %}{% if not is_popup %}
<ul class="object-tools">
{% block object-tools-items %}
{% change_form_object_tools %}
{% endblock %}
</ul>
{% endif %}{% endif %}
{% endblock %}
<form {% if has_file_field %}enctype="multipart/form-data" {% endif %}{% if form_url %}action="{{ form_url }}" {% endif %}method="post" id="{{ opts.model_name }}_form" novalidate>{% csrf_token %}{% block form_top %}{% endblock %}
<div>
{% if is_popup %}<input type="hidden" name="{{ is_popup_var }}" value="1">{% endif %}
{% if to_field %}<input type="hidden" name="{{ to_field_var }}" value="{{ to_field }}">{% endif %}
{% if save_on_top %}{% block submit_buttons_top %}{% submit_row %}{% endblock %}{% endif %}
{% if errors %}
<p class="errornote">
{% if errors|length == 1 %}{% translate "Please correct the error below." %}{% else %}{% translate "Please correct the errors below." %}{% endif %}
</p>
{{ adminform.form.non_field_errors }}
{% endif %}
{% block field_sets %}
{% for fieldset in adminform %}
{% include "admin/includes/fieldset.html" %}
{% endfor %}
{% endblock %}
{% block after_field_sets %}{% endblock %}
{% block inline_field_sets %}
{% for inline_admin_formset in inline_admin_formsets %}
{% include inline_admin_formset.opts.template %}
{% endfor %}
{% endblock %}
{% block after_related_objects %}{% endblock %}
{% block submit_buttons_bottom %}{% submit_row %}{% endblock %}
{% block admin_change_form_document_ready %}
<script id="django-admin-form-add-constants"
src="{% static 'admin/js/change_form.js' %}"
{% if adminform and add %}
data-model-name="{{ opts.model_name }}"
{% endif %}
async>
</script>
{% endblock %}
{# JavaScript for prepopulated fields #}
{% prepopulated_fields_js %}
</div>
</form></div>
{% endblock %}
위의 html을 extend 해서 사용하는 방법도 있지만, 원하는 위치에 테이블을 두려고 이를 그대로 복사해와서 이를 편집해주었습니다.
<table style='border: 2px solid;'>
{% for i in product_list %}
<tr style="border: 1px solid">
<td style="border: 1px solid">
{{ i.title }}
</td>
<td style="border: 1px solid">
{{ i.creator }}
</td>
<td style="border: 1px solid">
{{ i.price }}
</td>
</tr>
{% endfor %}
</table>
추가한 코드입니다. 이를 아래 사진의 위치에 넣어주었습니다.
이렇게만 하면, 해당 html이 불러와졌을 때 출력하고자 하는 데이터가 전해지지 않아 출력을 할 수 없습니다. 그러므로 해당 html이 불러와지기 전에 view 선에서 먼저 보낼 데이터를 정해주어야 합니다. 이를 담당하는 메소드가 change_view 입니다.
사용한 코드는 아래와 같습니다. 해당 함수는 ModelAdmin 내부에서 override 해주면 됩니다. HTML과 아래의 change_view 함수 코드를 보면 충분히 이해를 하실 수 있을 것 같습니다.
def change_view(self, request, object_id, form_url='', extra_context=None):
extra = extra_context or {}
# 연관된 상품을 리스트업 하기 위한 코드
q = Ordertoproduct.objects.filter(orderid=object_id)
product_id_list = [i.productid for i in q]
q = []
for i in product_id_list:
dict = {}
p = Product.objects.get(id=i.id)
dict['title'] = p.product_information.title
dict['creator'] = p.creatorid.email
dict['price'] = p.product_information.price
q.append(dict)
extra['product_list'] = q
return super(OrderAdmin, self).change_view(request, object_id, form_url='', extra_context=extra)
댓글
이 글 공유하기
다른 글
-
[Django] admin에서 list_filter에 넣을 커스텀 필터를 만들 수 있을까?
[Django] admin에서 list_filter에 넣을 커스텀 필터를 만들 수 있을까?
2022.07.06 -
[Django] DjangoAdmin.SearchFields에 ChoiceField가 필요했어
[Django] DjangoAdmin.SearchFields에 ChoiceField가 필요했어
2022.06.11 -
[Django] 프로젝트에 toast-ui-editor 적용하기(django admin)
[Django] 프로젝트에 toast-ui-editor 적용하기(django admin)
2022.06.10 -
[Django] Django 프로젝트 중 맞닥뜨린 높은 벽들
[Django] Django 프로젝트 중 맞닥뜨린 높은 벽들
2022.05.24