관리자 페이지에서는 사용자가 정의한 모델에 대한 기본적인 CRUD 기능을 제공한다.
그러나 때로는 사용자가 직접 원하는 기능을 추가하고 싶을 수 있다.
이를 위해서 장고에서는 어드민(관리자) 페이지 커스터마이징 기능도 제공한다.
관리자 페이지 커스터마이징 작업은 admin.py 파일에서 이루어진다.
우선 각 모델에 해당하는 모델 관리자 클래스를 만들어 놓자.
대략적으로 admin.py 에서 정의한 모델 클래스는
추가적인 옵션
class ObjectAdmin(매개변수, 여러 개가 들어갈 수도 있다):
필드들(optional)
함수들(optional)
이렇게 구성된다.
admin.ModelAdmin
장고 어드민 인터페이스의 구현체라고 한다.
정확히 무슨 말인지는 모르겠다!
[이해하면 포스팅하기]
register
modelAdmin을 등록하기 위해서는 register 선언을 해 주어야 한다.
admin 파일에 코드를 작성한 뒤, 작성한 내용을 관리자 페이지에 반영하기 위해서 필요한 작업이다.
작성한 modelAdmin을 register으로 등록하는 방법은 두 가지가 있다.
1. 메소드 사용하기
admin.site.register(모델, 모델 어드민 클래스)
class AuthorAdmin(admin.ModelAdmin):
// code
admin.site.register(Author, AuthorAdmin)
2. 데코레이터(decorator) 사용하기
장고에서 @을 사용하여 추가적인 기능을 제공하는 것을 데코레이터(decorator)라고 한다.
@admin.register(모델)
class 모델 어드민 클래스(admin.ModelAdmin):
// 세부 코드
@admin.register(Author):
class AuthorAdmin(admin.ModelAdmin):
// code
또한 하나의 어드민 클래스에서 여러 모델을 관리할 수도 있기 때문에, 여러 개의 모델을 입력할 수도 있다.
@admin.register(모델1, 모델2, 모델3)
class 모델 어드민 클래스(admin.ModelAdmin):
// 세부 코드
관리자 페이지가 다른 어플리케이션과 연결되는 원리
settings.py의 INSTALLED_APPS 필드에는 기본값으로 django.contrib.admin이 추가되어 있다.
이 클래스가 settings.py에 추가되어 있다면, 앱(어플리케이션, 서버)이 시작하자마자 django.contrib.admin 클래스의 모듈은 INSTALLED_APPS 안에 있는, admin을 사용하는 다른 앱에 import 된다.
이게 가능한 이유는 django.contrib.admin의 autodiscover() 함수 때문이다.
autodiscover() 메소드는서버가 시작하자마자 INSTALLED_APPS에 등록된 다른 앱에서 admin을 사용하는 모델을 찾고, 그 모델들을 관리자 사이트에 등록시킨다.
autodiscover() 메소드는 서버 시작 시 모든 admin에 등록할 모델들을 자동으로 불러오지만, 관리자 페이지를 커스터마이징했을 때 일부 상황에서는 이 기능이 필요하지 않을 수 있다.
autodiscover() 메소드를 사용하고 싶지 않다면, django.contrib.admin 클래스 하위에 있는 apps.SimpleAdminConfig 클래스를 사용해야 한다. 원래 django.contrib.admin은 apps.AdminConfig 메소드를 기본값으로 사용했었다.
즉 django.contrib.admin은 아무 옵션도 추가하지 않을 경우 기본값으로 django.contrib.admin.apps.AdminConfig 클래스를 사용해 왔던 것이다.
그러나 autodiscover() 메소드를 사용하고 싶지 않다면 settings.py의 INSTALLED_APPS에 django.contrib.admin 을 지우고 django.contrib.admin.apps.SimpleAdminConfig를 추가하면 된다.
ModelAdmin 인터페이스의 옵션들
ModelAdmin은 규모가 큰 인터페이스이고, 그만큼 커스터마이징을 위한 여러 옵션을 추가할 수 있다.
옵션은 각 어드민 클래스의 필드 형식으로 지정하면 된다.
1. actions
actions의 값으로는 함수들의 리스트를 입력한다.
해당 어드민 클래스에서 사용할 수 있는 함수, 기능들을 나열할 수 있다.
2. actions_on_top / actions_on_bottom
True나 False를 입력한다.
actions 옵션으로 입력한 기능들을 페이지의 위에 표시할지, 아래에 표시할지를 지정한다.
class ProjectAdmin(admin.ModelAdmin):
actions_on_top = True
3. date_hierarchy
모델의 필드 중 DateField 또는 DateTimeField 타입인 필드 이름을 값으로 갖는다.
해당 모델의 데이터를 정렬할 때 입력한 필드의 날짜 순서대로 정렬해 준다.
역순으로 정렬하고 싶다면 필드 이름 앞에 - 을 붙이면 된다.
class ProjectAdmin(admin.ModelAdmin):
date_hierarchy = '-register_date'
4. empty_value_display
문자열을 값으로 받는다.
두 가지 방법으로 사용할 수 있다.
첫째로, 각 어드민 클래스의 필드 이름으로 empty_value_display를 사용해서 지정할 수 있다.
해당 모델의 필드 중 빈 값(null 또는 "" 공백 문자열)이 있다면 그 값을 관리자 페이지에서 어떻게 표시할지를 지정한다.
class UserAdmin(admin.ModelAdmin):
empty_value_display = 'EMPTY'
둘째로, 데코레이터를 사용해서 각 필드값을 리턴하는 함수 위에 붙여서 사용할 수 있다.
첫번째 방법에서는 해당 모델에 속한 모든 필드의 빈 값을 같게 나타내지만, 두 번째 방법을 사용하면 각 필드별로 빈 값을 다르게 표시할 수 있다.
class UserAdmin(admin.ModelAdmin):
list_display = {'id', 'view_username', 'view_userid'}
@admin.display(empty_value="no name")
def view_username(self, obj):
return obj.username
@admin.display(empty_value="no id")
def view_userid(self, obj):
return obj.userid
5. exclude
필드 리스트를 값으로 받는다.
제외하고 싶은 필드들이 있을 때, exclude의 값으로 입력한다.
class UserAdmin(admin.ModelAdmin):
exclude = ['birth-date', 'age']
// birth-date, age 필드를 제외한 모든 필드가 관리자 페이지에 나타남
6. fields
필드 이름 튜플을 값으로 받는다.
데이터를 수정(change)이나 추가(add)하는 페이지에서 fields의 값에 포함된 필드들만 나타나게 할 수 있다.
serializer.py에서 read-only로 지정된 필드들만 fields 리스트에 포함될 수 있다.
더 세부적인 작업을 하고 싶으면 fieldsets 옵션을 사용하자.
# models.py
class Homework(models.Model):
title = models.CharField('제목')
content = models.TextField()
teacher = models.ChoiceField(choices=TEACHER_LIST)
submission_date = models.DateTimeField()
# admin.py
class HomeworkAdmin(admin.ModelAdmin):
fields = ('title', 'content')
위 예시의 경우, 데이터를 추가 및 수정하는 페이지에서는 title과 content 필드에 대해서만 수정 및 추가 작업을 할 수 있다.
또한, fields 튜플 안에서 괄호()를 한번 더 사용하면, fields 튜플 안의 필드들을 한 줄로 나타낼 수 있다.
7. fieldsets
fields와 기본적인 역할은 같고, 튜플을 원소로 갖는 튜플 리스트(two-tuple)를 값으로 받는다. 처음 관리자 페이지에서 보는 카테고리 화면이 아니라, 데이터를 추가나 수정하는 페이지에서 선택한 필드를 그룹으로 묶어서 나타내는 데 사용한다.
fields 옵션에서는 필드 그룹이 하나만 있었다면, fieldsets 옵션에서는 하나의 모델에 대해서도 여러 필드 그룹을 만들 수 있다.
여러 개의 그룹을 만들고 싶다면 fieldsets 안에서 튜플을 여러 개 만들면 된다. 각 튜플은 "옵션"과 {} 딕셔너리로 이루어진다.
이런 식으로 만들면 된다.
fieldsets = (
("그룹_1의 이름", {
"fields": ('그룹_1에 들어갈 필드_1', '그룹_1에 들어갈 필드_2')
}),
("그룹_2의 이름", {
"fields": ('그룹_2에 들어갈 필드_1', '그룹_2에 들어갈 필드_2'),
})
)
# models.py
class Course(models.Model):
student_name = models.CharField()
lecturer_1 = models.ChoiceField(choices=LECTURER_LIST)
course_1 = models.ChoiceField(choices=LECTURER_LIST)
lecturer_2 = models.ChoiceField(choices=LECTURER_LIST)
course_2 = models.ChoiceField(choices=LECTURER_LIST)
lecturer_3 = models.ChoiceField(choices=LECTURER_LIST)
course_3 = models.ChoiceField(choices=LECTURER_LIST)
# admin.py
class CourseAdmin(admin.ModelAdmin):
fieldsets = (
("강의 1", {"fields": (('lecturer_1', 'course_1'))}),
// 그룹 이름을 '강의 1'로 설정
// 강의 1에 해당하는 필드들을 개별 그룹으로 표시
// 필드들을 한 줄에 표시
("강의 2", {"fields": ('lecturer_2', 'course_2')})
// 그룹 이름을 '강의 2'로 설정
// 강의 2에 해당하는 필드들을 개별 그룹으로 표시
// 각 필드는 한 줄을 차지함
)
또한 fieldsets 내부의 딕셔너리의 값으로 "fields" 뿐만 아니라 다른 값을 추가로 사용할 수도 있다.
대표적으로는 classes, description 등이 있다.
1) classes
해당 fieldset에 CSS 속성을 적용할 때 사용한다.
class CourseAdmin(admin.ModelAdmin):
fieldsets = (
(None, {
"fields": (('lecturer_1', 'course_1')),
"classes": ('wide', 'extrapretty')
}),
)
2) description
각 fieldset 위에 추가 텍스트를 넣을 때 사용한다.
또한 fields나 fieldsets 옵션을 따로 명시하지 않았다면, 장고에서는 기본값으로 AutoField가 아니고 editable=True로 된 필드들만 관리자 페이지에 포함시킨다.
fieldsets, list_display의 차이점
헷갈리는 부분이라 적어보았다.
fields와 fieldsets는 처음 관리자 페이지에서 모델명을 누르면 나오는 조회 페이지가 아니라, 조회 페이지에서 개별 데이터를 누르면 나오는 추가 및 수정 페이지에서 어떤 필드를 표시할지를 결정한다.
반면 list_display는 관리자 페이지 시작 화면에서 모델명을 누르면 나오는 조회 페이지에서 어떤 필드를 표시할지를 결정한다.
8. filter_horizontal & filter_vertical
필드 이름 튜플을 값으로 받으며, ManyToManyField(다대다 필드) 에서만 작동한다.
fieldsets과 마찬가지로 조회 페이지가 아니라 추가 및 수정 페이지에서 작동한다.
many-to-many field 특성상 선택하는 가짓수가 많을 때는 다루기 어려울 수 있기 때문에, 간단한 인터페이스를 사용해서 데이터를 쉽게 추가 및 수정할 수 있게 했다.
filter_horizontal의 경우 선택되지 않은 가짓수(옵션)이 왼쪽, 선택된 옵션이 오른쪽 박스에 나타난다.
filter_vertical의 경우 선택되지 않은 옵션이 위쪽, 선택된 옵션이 아래쪽 박스에 나타난다.
9. form
관리자 페이지에서 모델뿐만 아니라 폼 데이터를 추가 및 수정할 때 사용한다.
# forms.py
class CarForm(forms.ModelForm):
class Meta:
model = Car
exclude = ['engine oil']
# admin.py
class CarAdmin(admin.ModelAdmin):
form = CarForm
위의 경우, admin-form-model이 연결되어 데이터를 수정 및 변경할 수 있다.
참고한 포스트
Admin actions | Django documentation | Django (djangoproject.com)
The Django admin site | Django documentation | Django (djangoproject.com)
장고 마스터하기 - 5장 - 김땡땡's blog (yonghyunlee.gitlab.io)
'server-side > Django' 카테고리의 다른 글
models: on_delete (0) | 2022.07.05 |
---|---|
admin: Inline, InlineModelAdmin (0) | 2022.07.02 |
conda 사용해서 가상환경 만들기 (0) | 2022.06.29 |
#2. Django 관리자 페이지 접근하기 (0) | 2022.06.26 |
#1. 프로젝트 실행환경 만들기(복습) (0) | 2022.06.24 |