정적(static) 파일 사용하기
정적 파일은 css나 js 같은 파일들을 의미한다. 이를 사용하기 위해선 static 폴더를 만들고 그 안에 파일을 저장한 후 사용하는 것이 일반적이다. 때문에, polls 폴더 밑에 static 폴더를 만들고 그 안에 polls 폴더를 하나 더 만들고, style.css 파일을 추가한다. 잘 생성했다면, 다음과 같은 모양이 나올 것이다.
그리고, style.css에 다음과 같이 기술한다.
li a {
color: green;
}
다음으로, polls/templates/polls/index.html의 <head>태그 사이에 다음과 같이 코드를 추가하자.
{% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'polls/style.css' %}">
{% static %} 템플릿 태그는 정적 파일의 절대 URL을 생성한다.
이제, 웹사이트를 확인하면, li로 설정했던 태그들이 초록색을 띄는 것을 볼 수 있다.
관리자 폼 커스터마이징
현재 관리자 페이지는 목록 화면에 투표 제목만 있고, 수정과 같은 기능을 할 수 없는 답답한 형태이다. 이를 해결하기 위해서는 django에 원하는 옵션을 알려주고, 커스터마이징 하면 된다. polls/admin.py를 다음과 같이 수정하자.
from django.contrib import admin
from .models import Question
class QuestionAdmin(admin.ModelAdmin):
fields = ['pub_date', 'question_text']
admin.site.register(Question, QuestionAdmin)
모델의 관리자 옵션을 변경할 때, admin.ModelAdmin을 상속받는 클래스를 만들고 admin.site.register()에 두번째 인수로 전달한다.
지금 당장은 date, time의 두 필드만 관리해서 상관이 없지만, 수십 개의 필드가 있는 폼은 fieldset으로 관리하는 것이 좋다. fieldset으로 한번 사용해보겠다.
from django.contrib import admin
from .models import Question
class QuestionAdmin(admin.ModelAdmin):
fieldsets = [
(None, {'fields': ['question_text']}),
('Date information', {'fields': ['pub_date']}),
]
admin.site.register(Question, QuestionAdmin)
fieldsets 변수를 이용해 관리자의 입력 및 수정 화면에서 각 항목들을 그룹화하고 그룹의 이름까지 설정할 수 있다. 각 튜플({ })의 첫번째 요소는 fieldset의 제목이다.
하지만, 아직도 부족하다. 우리는 Choice라는 모델을 만들었음에도 불구하고, Question은 선택 사항을 표시할 수 없다. 일단 polls/admin.py에서 Choice 모델을 import 해준다.
from .models import Question, Choice
다음, 답변 항목을 같이 등록하고 수정할 수 있도록 수정하려고 한다. 다음과 같이 수정한다.
from django.contrib import admin
from .models import Choice, Question
class ChoiceInline(admin.StackedInline):
model = Choice
extra = 3
class QuestionAdmin(admin.ModelAdmin):
fieldsets = [
(None, {'fields': ['question_text']}),
('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
]
inlines = [ChoiceInline]
admin.site.register(Question, QuestionAdmin)
ChoiceInline 클래스를 살펴보자.
지금은 Choice option이 3개밖에 안되니까 많이 불편하지는 않는데, 그럼에도 입력 화면이 너무 길다는 느낌이 든다. 답변을 관리하는 형태를 바꿔보자. ChoiceInline 클래스의 부모 클래스를 TabularInline으로 변경하자. 마찬가지로, polls/admin.py에서 변경하자.
class ChoiceInline(admin.TabularInline):
model = Choice
extra = 3
TabularInline을 사용하면, 인라인 아이템을 테이블 형식으로 보여줘 관련된 객체는 좀 더 조밀한 형식으로 표현된다.
확인을 해보면 다음과 같이 보여질 것이다.
관리자 화면 목록 커스터마이징
/admin/polls/question/에 보이는 목록을 보자. 현재는 투표 질문만 보이도록 설정되어있는데, 간편하게 발행일이나 여러 항목을 보이고 싶어 다음과 같이 수정하려고 한다.
목록에 보이는 항목을 변경하려면 list_display이라는 옵션을 사용한다. 이 옵션은 객체의 변경 목록 페이지에서 열로 표시할 필드 이름들의 튜플이다. 즉, 변수의 값은 튜플로 출력하고자 하는 항목을 묶어서 설정한다.
polls/admin.py을 다음과 같이 수정한다.
class QuestionAdmin(admin.ModelAdmin):
fieldsets = [
(None, {'fields': ['question_text']}),
('Date information', {'fields': ['pub_date']}),
]
list_display = ('question_text', 'pub_date', 'was_published_recently')
inlines = [ChoiceInline]
항목을 변경하면 목록에 바로 반영된 것을 볼 수 있다. 하지만, 출력되는 모양이 영 예쁘지 않다. was_published_recently가 True로 나오는 것이 맘에 들지 않아 다음과 같이 수정하려고 한다. polls/models.py를 수정한다.
class Question(models.Model):
(중략)
def was_published_recently(self):
now = timezone.now()
return now - datetime.timedelta(days=1) <= self.pub_date <= now
was_published_recently.admin_order_field = 'pub_date'
was_published_recently.boolean = True
was_published_recently.short_description = 'Published recently?'
간단하게 각 옵션을 설명해보면 다음과 같은 기능을 한다.
- admin_order_field : 해당 값의 기준으로 정렬
- boolean : 불리언 값인지 설정한다. True 설정 시 아이콘으로 나타난다.
- short_description : 해당 필드의 헤더 이름을 설정한다.
자 이제 마지막 수정이 남았다.
관리자 페이지에 질문 검색 기능과 필터링 기능을 추가해보자. 검색과 필터 기능은 QuestionAdmin 클래스를 변경하면 된다. polls/admin.py에 list_filter과 search_fields 변수를 추가해보자.
class QuestionAdmin(admin.ModelAdmin):
fieldsets = [
(None, {'fields': ['question_text']}),
('Date information', {'fields': ['pub_date']}),
]
list_display = ('question_text', 'pub_date', 'was_published_recently')
inlines = [ChoiceInline]
list_filter = ['pub_date']
search_fields = ['question_text']
코드를 변경하고 새로고침을 해보자.
완성이다!!!
참고로, 관리자페이지의 디자인을 변경하고 싶다면, django/contrib/admin/templates를 수정하면 된다.
추후에 만져보게 되면 더 내용을 추가해야지!!