티스토리 뷰

Django

localLibrary 관리자 페이지

editor752 2020. 8. 13. 09:36

2020/08/04 - [Django] - localLibrary 모델(models.py) 편집

 

localLibrary 모델(models.py) 편집

2020/08/03 - [Django] - localLibrary 뼈대 만들기 localLibrary 뼈대 만들기 본 내용은 Django 튜토리얼 사이트를 공부하면서 내용을 정리한 것이다. TOC 0. 선행 과제 1. 프로젝트 생성 2. 애플리케이션 생성 3..

editor752.tistory.com

본 내용은 Django 튜토리얼 사이트를 공부하면서 내용을 정리한 것이다.

[TOC]

  1. 모델(Models) 등록하기
  2. 관리자(superuser) 만들기
  3. 관리자로 로그인
  4. 관리자 사이트 사용자화
    1. ModelAdmin 클래스 등록하기
    2. 목록 뷰(list view) 설정
    3. 목록 필터 추가
    4. 세부 뷰 레이아웃(detail view layout) 수정
    5. 인라인 편집(Inline editing of associated records)

1. 모델(Models) 등록하기

주지하다시피 앞에서 Author, Genre, Book, BookInstance, Language 모델을 각각 클래스로 정의해 두었다. 이 모델을 admin.py에 등록해 주어야 한다. 따라서 해당 파일을 편집기로 열고 아래의 코드를 추가한다.

from catalog.models import Author, Genre, Book, BookInstance, Language

admin.site.register(Book)
admin.site.register(Author)
admin.site.register(Genre)
admin.site.register(BookInstance)
admin.site.register(Language)

이 코드는 모델들을 import하고 그것들을 등록하기 위해 admin.site.register 를 호출한다.

2. 관리자(superuser) 만들기

사이트에 대한 모든 접속 권한과 필요한 허가를 가진 superuser 계정은 manage.py를 사용해서만들 수 있다. 아래의 명령을 실행하면 관리자 계정명과 비밀번호를 설정하는 단계를 거쳐 관리자 계정이 생성된다.

python3 manage.py createsuperuser

관리자 계정을 만든 다음에는 서버를 재실행해 주어야 한다.

python3 manage.py runserver

3. 관리자로 로그인

관리자 페이지에 로그인하기 위해서는, /admin URL(예: http://127.0.0.1:8000/admin)으로 접속해야 한다. 그러면 앞서 superuser의 userid와 password를 입력하여 관리자 페이지에 접속할 수 있다(세부 정보를입력한 후에는 로그인 페이지로 리디렉션되고 /admin URL로 돌아간다
).

지금까지 따라오느라 고생이 많았다. 지금까지 만든 것들이 제대로 동작하는지 확인해 보자. 각각의 책마다 여러 개의 레코드(물리 책, BookInstance)를 만들자. 상태(Status)를 최소한 몇 개의 레코드는 대여 가능(Available)로 설정하고, 나머지는 대여 중(On loan)으로 설정하라. 만약 상태가 대여 불가능(not Available)이면, 만기 날짜도 같이 설정한다.

4. 관리자 사이트 사용자화

  • 관리자 사이트의 사용자화(customisation)에 관련한 자세한 레퍼런스(reference)는 The Django Admin site를 참고하기 바란다.

4-1. ModelAdmin 클래스 등록하기

관리자 사이트에서 모델이 보여지는 방식을 변경하려면 ModelAdmin 클래스(레이아웃을 나타내는)를 정의한 후 모델 안에 등록해야 한다. 먼저 catalog 애플리케이션의 admin.py(/locallibrary/catalog/admin.py) 파일을 열어 원래 있던 Author 모델에 대한 등록(registration)을 주석으로 처리한다.

# admin.site.register(Author)

그런 다음 아래와 같이 ModelAdmin에 해당하는 AuthorAdmin 클래스를 정의한다. 그리고 이 클래스를 이용하여 Author 모델을 재등록한다.

# Define the admin class
class AuthorAdmin(admin.ModelAdmin):
    pass

# Register the admin class with the associated model
admin.site.register(Author, AuthorAdmin)

BookBookInstance 모델의 등록도 수정한다. 그런데 이번에는 다른 방식을 사용으로 수정할 것이다. 모델들을 등록(register)하기 위해 @register 데코레이터(decorator)를 대신 사용한다. 이는 admin.site.register() 구문과 정확히 똑같이 작동한다.

note: 데코레이터는 함수 등을 수정하지 않은 상태에서 추가 기능을 구현할 때 사용한다. 이에 관련해서는 다음 페이지를 참고하기 바란다.

# Register the Admin classes for Book using the decorator
@admin.register(Book)
class BookAdmin(admin.ModelAdmin):
    pass

# Register the Admin classes for BookInstance using the decorator
@admin.register(BookInstance) 
class BookInstanceAdmin(admin.ModelAdmin):
    pass

지금까지 관리자 사이트들 사용자화하기 위한 기본 틀을 갖추었다. 실제로 사용자화를 하기 위해서는 ModelAdmin 클래스의 내용(현재는 pass로 되어 있는 부분)을 채워야 한다. 이제 이 부분을 채워갈 것이다.

4-2. 목록 뷰(list view) 설정

현재 Locallibrary에서는 저자(Authoer) 모델의 __str__() 메소드에서 생성되는 객체 이름(저자명)을 사용하여 저자 목록을 만든다. 그런데 경우에 따라서는 동명이인이 있을 수 있다. 동명이인을 구분하거나, 각각의 저자마다 추가 정보를 보여주어야 필요가 발생하는 것이다. 이때 list_display를 사용해서 view에 추가적인 필드를 추가할 수 있다.
편집 전 저자 페이지는 아래와 같다.

AuthorAdmin 클래스를 아래와 같이 편집하자.

class AuthorAdmin(admin.ModelAdmin):
    list_display = ('last_name', 'first_name', 'date_of_birth', 'date_of_death')

편집 후에는 아래와 같이 성과 이름, 생년과 졸년을 바로 확인할 수 있게 바뀐다.

다음으로 Book 모델을 아래와 같이 편집한다. 편집 전 책 페이지는 아래와 같다.

class BookAdmin(admin.ModelAdmin):
    list_display = ('title', 'author', 'display_genre')

다른 항목과 달리 genre 필드는 ManyToManyField이기 때문에 list_display가 직접적으로 특정할 수 없다. 대신 정보를 문자열로 받기 위해서 display_genre 함수를 이곳이 아닌 models.pyBook 모델에 별도로 정의하여야 한다. 그 코드는 아래와 같다.

    def display_genre(self):
        """Create a string for the Genre. This is required to display genre in Admin."""
        return ', '.join(genre.name for genre in self.genre.all()[:3])

    display_genre.short_description = 'Genre'

이 코드는 genre 필드의 첫 세 가지 값들의 문자열을 생성한다(만약 존재한다면요). 그리고 이 메소드는 관리자 사이트에서 사용될 수 있는 short_description을 만든다.
여기까지 무사히 마쳤다면 Book 페이지는 아래와 같이 바뀔 것이다.

이제 BookInstance 페이지를 변경하기 위해 아래와 같이 이전 파일(admin.py)을 아래와 같이 편집하자. 수정 전 페이지는 아래와 같다.

# Register the Admin classes for BookInstance using the decorator
@admin.register(BookInstance)
class BookInstanceAdmin(admin.ModelAdmin):
    list_display = ('book', 'status', 'due_back', 'id' )

BookInstance 페이지에서 서명, 현재 상태, 반납 일자, 책 고유id를 확인할 수 있게 수정하는 코드이다. 코드가 반영되면 아래와 같이 페이지가 바뀐다.

4-3. 목록 필터 추가

목록을 필터링하여 보여줄 수도 있다. 그러기 위해서는 list_filter 속성 안에 필터링을 하고자 하는 목록을 나열하면 된다. admin.pyBookInstanceAdmin 클래스에 아래의 코드를 추가해 보자.

class BookInstanceAdmin(admin.ModelAdmin):
    list_filter = ('status', 'due_back')

목록 뷰(list view)는 이제 위와 같이 오른쪽에 필터 상자를 갖게 된다.

4-4. 세부 뷰 레이아웃(detail view layout) 수정

기본적으로, 세부 뷰(detail view)는 모델에 선언된 순서대로 모든 목록들을 수직으로 나열한다. 여기서는 ① 표시될(혹은 제외될) 필드 지정 및 배치 제어, ② 세부 뷰 구역 나누기(Sectioning the detail view), 등을 알아볼 것이다.

어떤 필드들이 보여지고 배치될지 제어하기

admin.pyAuthorAdmin 클래스에 아래의 코드를 추가하자.

class AuthorAdmin(admin.ModelAdmin):
    fields = ['first_name', 'last_name', ('date_of_birth', 'date_of_death')]

fields 속성에 보여져야 할 필드들만을 순서대로 나열한다. 필드들은 기본적으로 수직적으로 표시된다. 그런데 위의 date 필드와 같이 튜플 안에 그룹짓는다면 이 필드들은 수평적으로 표시된다.

실제 코드를 적용해 보면 위와 같이 성, 이름이 제시되는 순서가 이름, 성으로는 바뀐 것을 확인할 수 있다. 그리고 생몰 연대도 수평으로 배치되어 있다. 그런데 간혹 수평 나열은 반영되지 않은 채 생몰연대가 여전히 수직으로 나열되는 것으로 보이는 경우가 있을 수 있다. 이럴 땐 다른 것을 확인해 보기 전에 브라우저의 가로 길이를 확대해 보자.

note: 양식(form)에서 제외되어야 할 속성들의 목록을 선언하기 위해 exclude 속성을 사용할 수 있다.

세부 뷰 구역 나누기(Sectioning the detail view)

fieldsets 속성을 사용하여, 세부 양식 안의 연관된 모델 정보를 그룹화할 수 있다. 이때 sections를 추가할 수 있다.
BookInstance에는 책이 무엇인지(i.e. name, imprint, id 등) 그리고 이것을 언제 빌릴 수 있는지 (status, due_back)에 대한 정보가 담겨있다. admin.pyBookInstanceAdmin을 아래와 같이 수정해 보자.

@admin.register(BookInstance)
class BookInstanceAdmin(admin.ModelAdmin):
    list_filter = ('status', 'due_back')

    fieldsets = (
        (None, {
            'fields': ('book', 'imprint', 'id')
        }),
        ('Availability', {
            'fields': ('status', 'due_back')
        }),
    )

각각의 섹션엔 고유한 제목(또는 제목을 원하지 않을 경우, None)과 사전의 필드와 관련된 튜플이 지정된다. 위의 경우에는 이름 없는 섹션에 book, imprint, id가 하나로 묶이고, 다음 Available 섹션으로 status', 'due_back 필드가 하나로 묶이게 된다.
코드가 적용되면 아래와 같이 페이지 레이아웃이 바뀐다.

4-5. 인라인 편집(Inline editing of associated records)

연관된 필드를 동시에 추가하는 것이 가능하다. 예를 들어, 세부 사항 페이지에서 책 정보 그리고 특정한 복사본에 대한 정보 둘 모두를 보여줄 수 있다. 이를 위해서는 inline을 선언하고 TabularInline (수평적 레이아웃)타입 또는 StackedInline (기본 모델 레이아웃과 같은 수직적 레이아웃)을 선택할 수 있다.
아래와 같이 BooksInstanceInline 클래스를 정의하고 BookAdmin 클래스를 수정해보자.

class BooksInstanceInline(admin.TabularInline):
    model = BookInstance

@admin.register(Book)
class BookAdmin(admin.ModelAdmin):
    list_display = ('title', 'author', 'display_genre')
    inlines = [BooksInstanceInline]

그러면 아래와 같이 Book의 세부 페이지에 BookInstance의 세부 내용이 추가된다.

추가

저자(Author) 관리자 페이지의 저자 세부 항목 뷰에 책 세부 정보를 인라인으로 추가해 보자. 앞서 Book/BookInstance의 방법을 원용하면 된다. 먼저 BookInline 클래스를 선언하고 이 클래스를 AuthorAdmin클래스의 inlines 속성에 지정해 주면 된다. 아래와 같이 코드를 추가하면 된다.

#  inline 추가
class BookInline(admin.StackedInline):
    model = Book
    extra = 0

#  Define the admin class
class AuthorAdimn(admin.ModelAdmin):
    list_display = ('last_name', 'first_name', 'date_of_birth', 'date_of_death')
    fields = ['first_name', 'last_name', ('date_of_birth', 'date_of_death')]
    inlines = [BookInline]

Book/BookInstance과 다른 점은 BookInline 클래스를 정의할 때 StackedInline을 사용한 것과 extra 속성을 추가한 점이다. StackedInline은 목록을 세로로 배치하도록 하며, extra 속성은 내용이 빈 항목을 여유분으로 몇 개 더 보여줄지를 지정하는 속성이다. Book/BookInstance에서는 따로 지정하지 않아 기본값(?)인 3개 생성되었지만 여기에서는 0으로 지정하였다.
이 코드를 적용하면 아래와 같이 페이지가 바뀐다.

굉장히 많을 것을 해냈다. 이러한 방식으로 관리자 페이지를 자신의 구미에 맞게 편집할 수 있다는 사실을 확인했다. 꽤 많은 것을 해냈지만 정작 사용자가 볼 수 있는 화면은 아무것도 만들지 않았다는 사실을 상기해야 한다. 다음에는 사용자가 접근할 수 있는 페이지를 다루어 보자.

2020/08/15 - [Django] - localLibrary 홈페이지 만들기 : index 페이지

 

localLibrary 홈페이지 만들기 : index 페이지

2020/08/13 - [Django] - localLibrary 관리자 페이지 localLibrary 관리자 페이지 2020/08/04 - [Django] - localLibrary 모델(models.py) 편집 localLibrary 모델(models.py) 편집 2020/08/03 - [Django] - loca..

editor752.tistory.com

 


댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함
05-05 23:33