Inline

모델 A가 모델 B를 ForeignKey로 가질 때, 모델 A는 모델 B에 의존한다. 

모델 A의 각 데이터마다 해당하는 모델 B의 데이터를 보고 싶을 때, inline을 사용한다. 

 

# models.py
class Home(models.Model):
	id = models.IntegerField()
	address = models.CharField()

class Person(models.Model):
	id = models.IntegerField()
	name = models.CharField()
	home = models.ForeignKey(Home, on_delete=models.CASCADE)
# admin.py
class PersonInline(admin.StackedInline):
	model = Home	# 해당 클래스가 외래키로 갖는 모델 입력
    
class HomeAdmin(admin.ModelAdmin):
	inlines = [PersonInline]	# 해당 클래스를 참조하는 다른 inline 클래스 입력

 

예시에서는 Person이 Home을 ForeignKey로 갖는다.

하나의 home 인스턴스를 참조하는 person 객체는 여러개일 수 있다. 

만약 각각의 home을 참조하는 person 객체들을 한 번에 보고 싶다면 inline을 활용하면 된다. 

 

InlineModelAdmin

장고에서도 inline을 사용하기 위한 InlineModelAdmin 클래스를 제공한다. 

(InlineModelAdmin은 ModelAdmin의 하위 클래스이다.)

InlineModelAdmin 클래스는 두 개의 하위 클래스인 StackedInline, TabularInline으로 구성되어 있는데, 두 클래스의 차이는 렌더링에 사용되는 템플릿의 차이 정도라고 봐도 무방하다. 

 

*렌더링(rendering):

작성한 웹사이트 코드를 사용자가 보는 웹 페이지로 바꾸는 과정. 

렌더링 엔진을 사용하여 렌더링을 한다. 

 

+) 또한 각 인스턴스를 참조하는 inline은 개별 데이터를 조회하는 화면에서 볼 수 있다. 

 

 

InlineModelAdmin options

InlineModelAdmin의 옵션 중 ModelAdmin의 필드와 다른 것, 재정의한 필드 등을 살펴보자. 

 

1) models

Inline 클래스가 어떤 모델의 데이터를 나타내는지를 입력한다. 

 

2) can_delete

데이터 조회 페이지가 아니라 inline이 나온 페이지에서도 데이터를 삭제할 수 있는지를 결정한다. 

기본값은 True이며 이 경우 inline에서 바로 데이터를 삭제할 수 있다. 

False로 입력하면 inline에서는 데이터를 삭제할 수 없고, inline에 해당하는 클래스(모델)의 데이터 조회 페이지에서 데이터를 삭제할 수 있다. 

 

3) fields

inline에서도 필드를 선택적으로 보여줄 수 있다. 

 

4) exclude

fields와 기능은 같은 반대 옵션이다. inline에서는 사용자에게 이 안에 입력한 필드만 제외하고 보여준다. 

 

5) inlines

inline 클래스에서도 또 다시 inline을 지정할 수 있다. 

 

6) fk_name

해당 inline이 나타내는 클래스에 여러 개의 ForeignKey 필드가 있을 때 사용한다.

여러 개의 ForeignKey 필드 중에서 어떤 필드를 참조하여 inline을 생성할지를 결정한다. 

# models.py
class Request(models.Model):

    user = models.ForeignKey(User, on_delete=models.CASCADE)
    project = models.ForeignKey(Project, on_delete=models.CASCADE)
    request_state = models.IntegerField()
    name = models.CharField()
    deadline = models.DateTimeField()
    contents = models.TextField()
    price = models.IntegerField()


# admin.py
class RequestInline(NestedStackedInline):
    model = Request
    fk_name = 'project'

RequestInline 클래스는 Request 모델에 대한 inline을 담당한다. 

그러나 Request 모델은 2개의 ForeignKey(User, Project)를 갖고 있다. 

따라서 inline을 생성할 때 개별 User에 대해서 inline을 생성할지, 개별 project에 대해서 inline을 생성할지를 정해 주어야 한다. 

여기서는 fk_name = 'project' 으로 project 필드를 기준으로 inline을 생성한다고 지정했다. 

 

7) max_num

하나의 데이터를 조회할 때, 최대 몇 개의 inline 데이터를 표시할지를 지정한다. 

 

8) formfield_overrides

딕셔너리 형태의 값을 받는다. 

모델에서 정의한 특정 필드를 관리자 페이지에서만 지정된 형식으로 나타낼 수 있게 해 준다. 

 

# models.py
class Person(models.Model):
	id = models.BigIntegerField()
	name = models.CharField(max_length=30)
	introduce = models.CharField(max_length=500)
    
# admin.py
class PersonAdmin(admin.ModelAdmin):
	formfield_overrides = {
		models.BigIntegerField: {'widget': Textarea(attrs={'rows':1, 'cols':15})}
		models.BigIntegerField: {'widget': Textarea(attrs={'rows':2, 'cols':25})}
	}

모델 Person을 조회하는 관리자 페이지에서는 models.BigIntegerField 타입인 필드를 Textarea()의 형식으로 나타낼 수 있다. (CharField도 마찬가지이다. )

 

 

<잘 모르겠는 options> - 다음에 공부하기!

-formset

-form

-extra

 

 

참고한 포스트

The Django admin site | Django documentation | Django (djangoproject.com)

 

+ Recent posts