Django는 사이트 편리하게 모델을 관리할 수 있도록 관리자 기능 페이지를 기본적으로 제공한다.
오늘은 Admin 페이지를 활용하는 방법에 대해 알아보려고 한다.
Admin 페이지 접속하기
우선, Admin 페이지에 접속하려면, `superuser`(관리자)를 생성해야 한다.
다음 `createsuperuser` 명령어를 입력해서 Admin 페이지에 접근한다.
python manage.py createsuperuser
사용자 이름(Username) : admin
이메일 주소:
Password:
Password (again):
Superuser created successfully.
초기에 관리자 사이트에 들어가게 되면 user와 Groups만 볼 수 있다. 사전에 작성한 모델을 올려보도록 하자.
- 사전에 프로젝트와 앱을 생성하고 모델을 정의했다.
- makemigration, migrate으로 마이그레이션을 했다.
커스텀한 User 모델, 그룹 표시하기
admin.site.register(UserModel, UserAdmin)
admin.site.unregister(Group)
커스터마이징 옵션
해당 앱의 `admin.py` 파일에 모델을 관리자 페이지에 등록할 수 있다. 커스텀이 필요한 경우에는 데코레이터를 이용해 클래스를 작성한다.
from django.contrib import admin
from gs25.models import Market, Product
# Register your models here.
# 커스텀이 필요하지 않는 경우
admin.site.register(Market)
# admin.site.unregister(Market)
# 커스텀이 필요한 경우
@admin.register(Product)
class Product(admin.ModelAdmin):
list_display = ('name', 'price',)
list_display_links = ('name',)
ordering = ('name') # 정렬 순서를 정한다.
list_display
Admin 사이트에 보여질 필드를 정의하는 옵션이다.
- `ManytoManyField`는 지원하지 않는다.
- 리스트나 튜플 형태로 작성한다.
- `list_display_links` 옵션은 링크 기능을 추가할 필드를 지정하는 옵션이다. 해당 링크를 클릭하면 정보를 수정할 수 있다.
다음과 같이 함수를 작성해서 관리자 페이지에 보여질 값도 커스터마이징할 수 있다.
@admin.register(Product)
class Product(admin.ModelAdmin):
list_display = ('name', 'price', 'market_count')
def market_count(self, product):
return product.market.count()
readonly_fields
수정이 불가능하고 읽기만 가능한 필드를 표시 할 수 있다.
list_display = ('name', 'price', 'market_count',"created_at", "updated_at",)
readonly_fields = ("created_at", "updated_at",)
list_filter
Admin 사이트에 보여질 필드를 필터링하는 옵션이다.
`django-admin-rangefilter`를 설치하면 날짜 범위를 지정하여 필터링할 수 있다.
@admin.register(Product)
class Product(admin.ModelAdmin):
list_display = ('name', 'price',)
list_display_links = ('name',)
list_filter = ('group', 'expire_date') # Datetime 필드는 날짜 옵션이 제공된다.
커스텀 필터링
Admin 사이트에 보여질 필드를 필터링을 커스터마이징할 수 있다.
예를 들어서, 해당 제품 중에 오뚜기 제품만 필터링해서 Product를 출력하는 필터 클래스를 작성해 필터링에 추가했다.
커스텀 필터링은 `SimpleListFilter`를 상속받아 filter 요소를 추가할 수 있다. 반드시, `title`, `parameter_name` 변수와 `lookups` `queryset` 메서드가 있어야 한다.
- title : 필터링 이름
- parameter)name : 필터에 사용할 컬럼 이름 (URL 쿼리 스트링에 사용된다.)
- lookups : 필터에 보이게되는 것을 작성하는 메서드
- queryset : 특정 필터를 클릭했을 때 동작 구현 메서드
class OddukiFilter(admin.SimpleListFilter):
title = "오뚜기 제품 필터링"
parameter_name = "Odduki"
def lookups(self, request, model_admin):
return [
("오뚜기", "오뚜기제품"), # (url쿼리, 페이지에 보여지는 이름)
]
def queryset(self, request, product):
word = self.value() # url 쿼리를 받는다.
if word:
return product.filter(name__contains=word)
return product
@admin.register(Product)
class Product(admin.ModelAdmin):
list_display = ('name', 'price', 'market_count')
list_display_links = ('name',)
list_filter = ('group', 'expire_date','market', OddukiFilter) # 추가
# product/?Odduki=오뚜기
search_fields
검색어를 입력하면 그 문자열과 맞는 필드를 찾는 옵션이다. 찾는 방식은 아래처럼 다양하게 존재하니 알맞게 선택하여 검색하면 된다.
- ^ : 검색어로 시작하는 경우
- = : 해당 문자열이 정확히 일치하는 경우(갯수 판단할 때 사용)
- 아무것도 없음 : 해당 문자열이 포함되는 경우
- @ : 단어나 구문을 검색할 때 사용한다.
- foreginkey__related_fieldname : ForeignKey 혹은 ManytoMany 필드를 조회할 때 사용한다.
# 커스텀이 필요한 경우
@admin.register(Product)
class Product(admin.ModelAdmin):
list_display = ('name', 'price',)
list_display_links = ('name',)
list_filter = ('group', 'expire_date')
search_fields = ('name', '=price',)
fieldsets
admin 페이지에서 데이터를 추가하거나 수정할 때 입력폼을 변경할 수 있다.
# 수정할 때 사용하는 입력 폼
fieldsets = (
("상품 정보", {'fields': ('name', 'price', 'group', 'expire_date')}),
("마켓 관련", {'fields': ('market',)}),
)
# 추가할 때 사용하는 입력폼
add_fieldsets = (
(None, {
'classes': ('wide',), # 넓은 폼 스타일을 적용한다.
'fields': ('name','price', 'group', 'expire_date', 'market')
}
),
filter_horizontal = ('market',)
Actions
Admin 페이지에서는 CRUD를 편리한 인터페이스를 이용하여 수행할 수 있다.
그 중에서 데이터를 삭제할 때 아래 액션 탭을 이용해 제거할 수 있다. 제거 외에도 커스터마이징해서 액션을 추가할 수 있다.
아래는 Action을 추가하는 함수를 정의했다. 반드시 `model_admin` 클래스에 action을 추가해야 한다.
- model_admin : 모델 Admin 클래스를 의미한다. 클래스 내부에 작성할 경우 `self`로 사용하면 된다.
- request : 요청을 나타내는 부분이다.
- Queryset : 사용자가 선택한 객체이다. ✅
@admin.action(description="판매 불가 제품으로 변경합니다.")
def bannedsale(model_admin, request, products):
# model_admin, request, Queryset
# bannedsale.short_description = "판매 불가 제품으로 변경합니다."
for product in products.all():
product.state = '판매 중지'
product.save()
messages.warning(request, '판매 중지 상품으로 변경되었습니다.')
@admin.register(Product)
class Product(admin.ModelAdmin):
actions = (bannedsale,)
Meta 내부 클래스
`models.py` 내부 Meta 클래스에서 관리자 화면에 보여지는 객체 이름을 단수형, 복수형에 따라 다르게 표시할 수 있다.
class Meta:
verbose_name = "상품" # 단수
verbose_name_plural = "상품들" # 복수
db_table = 'products' # 데이터베이스 테이블 이름을 변경 (반드시 마이그레이션 필수)
ordering = ['-name'] # 최신순(-)으로 admin 페이지 내 데이터를 정렬한다.
모델 명 뿐만 아니라 관리자 페이지에 표시되는 필드 명 또한 수정이 가능하다.
group = models.CharField(max_length=20, choices=GroupsChoice.choices,
help_text="해당 제품은 신선한 상품인가요?", verbose_name="상품 타입")
Admin styling
이번엔 어드민 페이지를 스타일링하는 방법이다. Django에는 스타일링 관련 다른 패키지들도 존재하니 Django Packages 사이트를 참조하면 된다. 저는 `Django-Grappelli`가 사용횟수가 많고 지금까지도 업데이트 되었기 때문에 이 패키지를 사용해보았습니다.
☕️ 마치며
오늘도 저의 포스트를 읽어주셔서 감사합니다.
설명이 부족하거나 이해하기 어렵거나 잘못된 부분이 있으면 부담없이 댓글로 남겨주시면 감사하겠습니다.
'Web > Django' 카테고리의 다른 글
[Django] Unit 테스트 코드 작성하기 (0) | 2024.01.10 |
---|---|
Django Rest Framework - (1 : API 테스트 해보기) (0) | 2023.12.25 |
[Django] DB 쿼리 최적화를 다양한 방법들을 정리해보았다. (0) | 2023.12.20 |
[Django] 쿼리셋으로 데이터 조회하기 (0) | 2023.12.20 |
Django - 객체 참조 관계 (0) | 2023.11.29 |