문제 상황
어느 날 사이트의 랜딩 페이지를 새로 만들게 되었다! 설문조사 형식의 폼이 있는 랜딩 페이지 였는데 소비자들이 알림 받길 원하는 리뷰를 선택할 수 있다. 소비자들이 여러 리뷰를 고를 수 있고 하나의 리뷰가 여러 사람의 선택을 받을 수 있기 때문에 N:M 관계이다.
이 상황은 저번에 1:N 관계를 접했을 때랑 비슷하다! (위 링크 참고!) 소비자들이 설문조사한 db들을 export할 때 제대로 된 값이 나오지 않았다. 소비자들에게 받은 정보를 잘 출력하고 싶다면 ManyToManyWidget을 사용하면 된다.
오늘도 공식문서 참고!
https://django-import-export.readthedocs.io/en/latest/api_widgets.html
ManyToManyWidget을 활용해보자!
#models.py
from django.db import models
RESIDENCE = (
('Heungdeok', '흥덕구'),
('Cheongwon', '청원구'),
('Seowon', '서원구'),
('Sangdang', '상당구'),
)
class HopeReviewKind(models.Model):
name = models.CharField(max_length=50, default="")
class TrustSurvey(models.Model):
residence = models.CharField(max_length=50, choices=RESIDENCE, null=False, blank=False)
hope_review = models.ManyToManyField(HopeReviewKind, related_name="selected_kind")
contact = models.CharField(max_length=50, null=False, blank=False)
created_at = models.DateTimeField(auto_now_add=True, null=True, blank=True)
👉🏻모델은 다음과 같다. TrustSurvey 모델에 설문조사한 내용이 저장된다. 설문조사에서 받는 내용은 거주지, 알림받고 싶은 리뷰 종류, 전화번호이고 언제 리뷰를 받았는지는 created_at을 통해 받는다.
✍🏻어떠한 리뷰를 받을지에 대한 field인 hope_review는 HopeReviewKind model을 ManyToMany로 참조하고 있다. 위에서 언급한대로 소비자도 여러 리뷰를 선택할 수 있고 하나의 리뷰도 여러 소비자의 선택을 받을 수 있기 때문이다.
🐰이제 admin.py를 어떻게 작성해야 하는지 살펴보자!
from django.contrib import admin
from import_export.widgets import ManyToManyWidget
from import_export import fields, resources
from .models import TrustSurvey
from import_export.admin import ImportExportModelAdmin
class TrustSurveyResource(resources.ModelResource):
residence = fields.Field(column_name = '거주지', attribute = 'residence')
hope_review = fields.Field(column_name = '원하는 리뷰',
attribute = 'hope_review',
widget = ManyToManyWidget('HopeReviewKind', field='name')
)
contact = fields.Field(column_name = '연락처', attribute = 'contact')
created_at = fields.Field(column_name = '입력시간', attribute = 'created_at')
class Meta:
model = TrustSurvey
fields = ('get_residence_display', 'hope_review', 'contact', 'created_at',)
export_order = ('residence', 'hope_review', 'contact', 'created_at',)
class TrustSurveyAdmin(ImportExportModelAdmin):
fields = ('residence', 'hope_review', 'contact',)
list_display = ('id', 'residence', 'hope_review', 'contact', 'created_at',)
resource_class = TrustSurveyResource
admin.site.register(TrustSurvey, TrustSurveyAdmin)
👉🏻모두 TrustSurveyResource를 살펴보자! 이전과는 다르게 모든 field의 column_name과 attribute를 설정해주었다. 왜냐하면 엑셀의 열이름을 model의 field명인 residence나 hope_review처럼 영어로 쓰지 않고 거주지, 원하는 리뷰 등 한글로 입력하고 싶었기 때문이다. 해당 db들은 엑셀로 export해서 대표님께 전달드려야 했기 때문에 엑셀 열이름이 한글로 되어있어야 정보를 확인하시기 편할 것 같아 한글로 설정했다!
✍🏻여기서 집중할 field는 hope_review field이다! widget을 ManyToManyWiget으로 설정했다. 형태는 다음과 같다.
class import_export.widgets.ManyToManyWidget(model, separator=None, field=None, *args, **kwargs)
- model: ManyToMany field가 참조하는 모델이다.
- separator: ','이 default로 설정되어 있다.
- field: 참조하는 모델을 찾기 위해 사용하는 field명이다. defalut는 pk이다.
✍🏻나는 HopeReviewKind model을 참조하기 때문에 해당모델을 썼다. 그리고 해당 모델의 name field로 찾을 수 있게 field명은 name으로 설정했다. 이렇게 설정하면 export할 때도 pk가 아닌 name으로 나온다! 아래 csv로 export한 예시를 보자!
👉🏻위젯을 설정하지 않으면 원하는 리뷰 부분에 해독 불가능한 landing.HopeReviewKind.None 출력
👉🏻위젯을 설정하면 깔끔하게 잘 나온다!ㅎㅎ
'그 땐 IT활동했지 > 그 땐 영일영 근무했지' 카테고리의 다른 글
[010/JS Library] chart.js | 범례 커스텀하기(2.4.0 version) (0) | 2022.03.20 |
---|---|
[010/JS Library] chart.js | 기본적인 사용법 (0) | 2022.03.19 |
[010/Django] django-import-export | Widget | DateTimeWidget (0) | 2022.03.12 |
[010/Django] django-import-export | Widget | ForeignKeyWidget (0) | 2022.03.11 |
[010/Django] django-import-export | 기본적인 사용법 (0) | 2022.03.10 |