그 땐 IT활동했지/그 땐 영일영 근무했지

[010/Django] django-import-export | Widget | ForeignKeyWidget

루이란 2022. 3. 11. 14:30
728x90

문제 상황

https://itwithruilan.tistory.com/69

db에 핸드폰 가게들을 잘 넣었고!(↑이전 포스팅 참고) 해당 가게들 각각에 해당하는 리뷰들을 넣어야 하는 상황이 왔다. 하나의 가게에 여러 리뷰가 달릴 수 있지만 하나의 리뷰에 여러 가게가 연결될 수 없기 때문에 각 테이블은 1:n관계이다.

여기서 리뷰 model의 다른 field는 문제없지만 store field가 ForeignKey이기 때문에 엑셀에서 어떤 값을 넣어야 하는지 감이 안 왔다! 기본적으로는 각 store의 id 값을 넣으면 되지만 수천개의 리뷰에 달하는 store의 id를 일일히 찾아볼 수는 없는 법..ㅜㅜ

그래서 구글링을 하다가 ForeignKeyWidget을 발견하고 사용해보니 완전 신세계.. 

 

아래 공식 문서도 참고!(widget 모음 페이지)

https://django-import-export.readthedocs.io/en/latest/api_widgets.html

 

Widgets — django-import-export 2.7.2.dev0 documentation

© Copyright 2012–2020, Bojan Mihelac Revision 0ad13e0c.

django-import-export.readthedocs.io

ForeignKeyWidget 사용하기!
#store/models.py
class Store(models.Model):
    name = models.CharField(max_length=70)
    location = models.CharField(max_length=140, null=True, blank=True)
    number = models.CharField(max_length=80, null=True, blank=True)

👉🏻store model은 다음과 같다.

#review/models.py
from store.models import Store

class CommunityReview(models.Model):
    store = models.ForeignKey(Store, on_delete=models.CASCADE, related_name='commu_review_owner')
    content = models.TextField(null=True, blank=True)
    rate = models.FloatField(null=True, blank=True)
    visit_date = models.DateTimeField(max_length=80, null=True, blank=True)

👉🏻store와 연결된 community review model은 다음과 같다. store field가 Store model을 참조하고 있다.

#admin.py
from django.contrib import admin
from .models import CommunityReview
from store.models import Store
from import_export.admin import ImportExportModelAdmin
from import_export.widgets import ForeignKeyWidget
from import_export import resources, fields


class CommunityReviewResource(resources.ModelResource):
    store = fields.Field(
        column_name = 'store',
        attribute = 'store',
        widget = ForeignKeyWidget(Store, 'location')
    )

    class Meta:
        model = CommunityReview
        fields = ('id', 'store', 'content', 'rate', 'visit_date',)
        export_order = fields


class CommunityReviewAdmin(ImportExportModelAdmin):
    fields = ('store', 'content', 'rate', 'visit_date',)
    list_display = ('id', 'store', 'content', 'rate', 'visit_date',)
    resource_class = CommunityReviewResource


admin.site.register(CommunityReview, CommunityReviewAdmin)

👉🏻CommunityReviewResource부분을 고쳐주면 된다. 이전 포스팅에서 메타클래스의 fields는 import할 데이터의 field명이다. 여기서 FK인 store만 위에서 따로 설정해준다.

👉🏻import_export의 메서드인 fields를 이용해 field를 정의한다. 

  • column_name: FK 관련 데이터를 가진 엑셀의 열이름이다. 
  • attribute: 데이터를 넣을 model의 field 이름이다. → 나의 경우 Community model의 store field
  • widget: 어떤 위젯을 쓸 지 지정한다.

✍🏻ForeignKeyWidget에 2개의 매개변수를 넣었다. 첫 매개변수인 Store는 참조할 모델로 필수로 넣어야 하는 값이다. 두 번째 매개변수인 'location'은 참조하는 특정 데이터(리뷰에 해당하는 가게)를 찾는 데 사용되는 관련 model의 field이다. 나의 경우 Store model의 location을 사용했다. 각각의 community review가 참조하는 store를 찾기 위해 location field를 활용한 것이다.

✍🏻그렇다면 엑셀에는 store 열에 해당 가게의 주소를 넣어야 한다!

👉🏻최종적으로 정리하자면 엑셀의 'store'라는 열을 찾아 해당 데이터값(Store model의 location)을 Store db에서 찾는다. 그리고 해당 데이터(가게의 주소)를 가진 가게를 찾아 CommunityReview model의 store field와 연결한다.

 

🐰이해하면 정말루 편리한 기능인데 풀어 설명하려니 어렵다ㅜㅜ 내가 전하고자 하는 바가 잘 전달됐으면 좋겠다ㅎ..

 

728x90