전에 User app에서 사용할 어드민 패널을 기본 패널을 확장하는 방식으로 만들어보았는데, 이번에는 User가 아닌 일반적인 앱에서 어드민 패널을 구성하는 방식을 정리해보았습니다. 딱히 다르지는 않지만 값으로 줄 수 있는 속성을 더 많이 알아보려고 합니다.
admin.py에서 볼 수 있는 옵션들은 다음에서 찾아볼 수 있습니다.
from django.contrib import admin
from . import models
@admin.register(models.Room)
class RoomAdmin(admin.ModelAdmin):
""" Room Admin Definition """
list_display = (
"name",
"country",
"city",
"price",
"address",
)
list_filter = (
"instant_book", "city", "country", "host__superhost",
)
search_fields = ["=city", "^host__username"]
search_fields
list_display나 list_filter는 앞 서 다룬 바가 있습니다. 여기서 처음 보는 건 search_fields입니다. 검색 창을 띄워줍니다.
각 검색어는 앞에 prefix를 붙임으로써 옵션을 줄 수 있습니다. 예를 들어 =를 붙이면 정확히 일치하는(대소문자 구별은 안 합니다) 것만 찾습니다.
Some (older) shortcuts for specifying a field lookup are also available. You can prefix a field in search_fields with the following characters and it’s equivalent to adding __<lookup> to the field:
^ | startswith |
= | iexact |
@ | search |
None (default) | icontains |
또, 모델 간의 연관관계를 타고 검색할 것을 지정할 수 도 있습니다.
host__username은, Room 모델에 있는(현재 코드가 작성된 경로가 rooms/admin.py이며 해당 admin에 연결된 model이 Room 모델임) host에 연결된 모델 내의 username을 의미합니다. 언더바 2개 인 것을 주의합시다. 이러한 방식은 serach 뿐만 아니라 모든 속성에서 사용할 수 있는 보편적인 것입니다.
예를 들어 list_filter에 "host__superhost" 항목을 추가할 수 있습니다. 그러면 Room 모델의 host와 연결된 다른 모델의 superhost 필드를 가져옵니다.
filter_horizontal
filter_horizontal = (
"amenity",
"facility",
"house_rules",
)
manytomany(다대 다)로 연결된 값들을 보여주는 패널을 바꿔줍니다. 훨씬 편해서 manytomany 관계인 속성들은 적용해주는 것이 좋습니다.
fieldsets
사실 이 필드도 전에 다뤄본 적이 있습니다. 여기서는 좀 더 자세하게 들어가봅시다.
상세 어드민 패널의 구조를 커스터마이징할 수 있습니다. 튜플이어야 하므로 값이 하나일 때도 ,(쉼표)를 잊지 말고 적어줍시다. 또, fields 외에 classes 속성을 통해서 필드셋을 디자인할 수도 있습니다.
classes
A list or tuple containing extra CSS classes to apply to the fieldset.
Example:
{ 'classes': ('wide', 'extrapretty'), }
자주 사용하는 건 collapse로, Hide & Show를 할 수 있습니다.
@admin.register(models.Room)
class RoomAdmin(admin.ModelAdmin):
""" Room Admin Definition """
fieldsets = (
(
"Basic Info",
{"fields": ("name", "description", "country", "address", "price")}
),
(
"Times",
{"fields": ("check_in", "check_out", "instant_book")}
),
(
"More About the Space",
{'classes': ('collapse',),
"fields": (
"amenity",
"facility",
"house_rules",
)}
),
(
"Spaces",
{"fields": (
"guests",
"beds",
"bedrooms",
"baths",
)}
),
(
"Last Detail",
{"fields": (
"host",
)}
)
)
ordering
ordering = ("name", "price", "bedrooms")
조회할 때의 순서를 지정할 수 있습니다.
위 예시의 경우 먼저 name순으로 정렬한 다음 price, bedrooms 순서로 정렬합니다.
list_display에 ManyToMany 속성 넣는 법 (QuerySet 이용)
본래 list_display에 다대 다 관계인 것을 넣으면 오류를 냅니다.(list_display should not be many-to-mayn)
이 경우, 함수를 사용해서 넣을 수 있습니다.
list_display = (
"instant_book",
# 함수를 살포시 넣어준다.
"count_amenities",
)
# 함수를 하나 만들어준다.
def count_amenities(self, obj):
# self는 해당 어드민 클래스
# obj는 현재 row이다.
print(obj.amenity.all()) """<QuerySet [<Amenity: Shower>, <Amenity: Wifi>]>"""
return obj.amenity.count()
# count_amenities라는 이름이 리스트에 뜨는 게 마음에 안들면 바꿔줄 수도 있다.
count_amenities.short_description = "amenities"
쿼리셋을 활용한 것입니다. Room과 amenity는 다대다 관계이므로 따로 related_name을 설정하지 않았어도 이름으로 그냥 가져올 수 있습니다.
FK 관계인 것은 xxx_set의 형태로 가져올 수 있겠지만, 가독성을 위해 related_name을 설정해주고 함수로 활용해 list_display에 넣어보았습니다.
class Photo(core_models.TimeStampedModel):
"""Photo Model Definition"""
caption = models.CharField(max_length=80)
file = models.FileField()
room = models.ForeignKey(
"Room", related_name="photos", on_delete=models.CASCADE)
def __str__(self):
return self.caption
def count_photos(self, obj):
return (obj.photos.count())
이와 관련된 내용은 아래 포스트를 참고하도록 합시다.
'Django, Flask > 🔫 Django' 카테고리의 다른 글
모델/어드민 내에서 로직 설계, 어드민 패널에 반영하기 (0) | 2020.05.12 |
---|---|
QuerySet 활용하기, related_name (0) | 2020.05.12 |
ForeignKey, ManyToManyField로 모델 연결하기 (0) | 2020.05.12 |
core를 이용하여 반복되는 Abstract model 설계 및 활용 (0) | 2020.05.12 |
User Admin panel Customizing (0) | 2020.05.11 |