Back-End/Python Django

[Django] [admin page] ForeignKey설정된 모델들을 한 화면에서 CRUD하기

Hoplin 2022. 2. 18. 10:07
반응형

models.py

아래와 같이 모델들이 선언되어있다고 하자, Question는 Choice의 Foreign Key이다. 즉 서로 연관된 데이터라는 의미이다. 연관된 데이터인 만큼 데이터 CRUD를 할때 같은 한 페이지에서 관리하면 더 좋다

 

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField(verbose_name='date_published')

    def __str__(self):
        return self.question_text

class Choice(models.Model):
    question = models.ForeignKey(Question,on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

    def __str__(self):
        return self.choice_text

하지만 기본적으로 admin페이지에서 모델을 등록하고 보면 아래와 같이 Question모델 따로 Choice모델 따로 설정/조회해 주어야 한다

따로따로 데이터를 넣어주어야 하고 데이터를 조회해야한다

이 두 모델을 한번에 볼 수 있도록 해줄 수 있다. Inline기능을 사용해 주면 된다. 기본적으로 admin.StackedInline클래스를 상속받은 클래스를 하나 정의해준다. 그리고 같이 Inline할 대상의 모델 등록 클래스에 Inline 변수에 클래스를 리스트 안에 넣어 입력한다.

class ChoiceInline(admin.StackedInline):
    model = Choice # Inline해줄 모델을 입력해준다.
    extra = 2 # 추가로 입력할수 있는 칸을 몇칸 생성할지를 나타내는 변수이다.

# Register your models here.
class QuestionAdmin(admin.ModelAdmin):
    fieldsets = [
        ('None',{'fields' : ['question_text']}),
        ('Date Information', {'fields' : ['pub_date'],'classes' : ['collapse']})
    ]
    inlines = [ChoiceInline]

admin.site.register(Question,QuestionAdmin)
admin.site.register(Choice)

 이와 같이 입력하고 보면 아래와 같이 한페이지에 같이 나오는것을 볼 수 있다.

주석으로도 적어놨지만 Inline클래스의 extra변수에 적어준 숫자 만큼 새로 등록할 수 있는창이 나오게 된다. 반대로 extra변수를 생략해주면 디폴트 값이 3이기 때문에 3개가 기본적으로 나타나는것을 볼 수 있다.

세로로 Inline을 하게 되면 데이터가 많아질 시 보기 불편할 수 있다. 그런 경우 테이블 형식처럼 바꿀수 있는데, admin.StackedInline대신 admin.TabularInline을 상속받아 클래스를 정의하면 된다.

class ChoiceInline(admin.TabularInline):
    model = Choice # Inline해줄 모델을 입력해준다.
    extra = 2

# Register your models here.
class QuestionAdmin(admin.ModelAdmin):
    fieldsets = [
        ('None',{'fields' : ['question_text']}),
        ('Date Information', {'fields' : ['pub_date'],'classes' : ['collapse']})
    ]
    inlines = [ChoiceInline]

admin.site.register(Question,QuestionAdmin)
admin.site.register(Choice)

반응형