LocalLibrary Model 정의 하기
이번에는 도서관 애플리케이션의 Model을 정의할 것이다.
먼저 models.py에 model 기본 클래스 models.Model을 포함하는
models 모듈을 추가 한다.
| from django.db import models # Create your models here. | cs |
① 장르(Gernre) 모델
아래의 장르(Genre) model의 코드를 복사해서
models 파일에 붙여넣기 해보자.
이 model은 책 카테고리에 관환 정보를 저장하는데 사용된다.
예를 들어
논픽션인지, 로맨스인지 등
장르를 자유 텍스트나 선택 목록으로
만들지 않고 모델을 이용해 만들었다.
가능한 값들이 하드 코딩되기 보다는
데이터베이스를 통해 관리되도록 하기 위함이다.
| class Genre(models.Model): """Model representing a book genre.""" name = models.CharField(max_length=200, help_text='Enter a book genre (e.g. Science Fiction)') def __str__(self): """String for representing the Model object.""" return self.name | cs |
이 모델은 하나의 name이라는 CharField 필드를 가지고 있따.
이것은 장르의 이름을 나타내며,
최대 200자로 제한 및 help_text 인수를 가지고 있다.
model의 마지막에는 __str__() 메소드를 선언했다.
이 메소드는 특정 레코드에 의해 정의된
장르의 이름을 리턴 한다.
verbose name도 정의 되지 않았기 때문에
필드는 폼에서 Name으로 호출될 것이다.
② 책(Book) Model
책 Model은 일반적으로
사용 가능한 책에 대한 정보들을 보여주지만,
대여 가능한 특정한 물리적 인스턴스나 복사본은 보여주지 않는다.
Model은 CharField를 사용하여 책의
title과 isbn을 나타낸다.
summery의 경우는 텍스트가 길어질 것으로 예상되기 때문에
TextField를 사용한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | from django.urls import reverse # Used to generate URLs by reversing the URL patterns class Book(models.Model): """Model representing a book (but not a specific copy of a book).""" title = models.CharField(max_length=200) author = models.ForeignKey('Author', on_delete=models.SET_NULL, null=True) # Foreign Key used because book can only have one author, but authors can have multiple books # Author as a string rather than object because it hasn't been declared yet in the file. summary = models.TextField(max_length=1000, help_text='Enter a brief description of the book') isbn = models.CharField('ISBN', max_length=13, help_text='13 Character <a href="https://www.isbn-international.org/content/what-isbn">ISBN number</a>') # ManyToManyField used because genre can contain many books. Books can cover many genres. # Genre class has already been defined so we can specify the object above. genre = models.ManyToManyField(Genre, help_text='Select a genre for this book') def __str__(self): """String for representing the Model object.""" return self.title def get_absolute_url(self): """Returns the url to access a detail record for this book.""" return reverse('book-detail', args=[str(self.id)]) | cs |
isbn 변수에 CharField()의 첫번째 인수에
'ISBN'를 지정하지 않았다면
Django에서 자동으로 Isbn으로 지정했을 것이다.
장르(genre)는 책이 여러 개의 장르를 가지고,
장르(genre)도 여러 개의 책을 가질 수 있는
다대다 필드(ManyToManyField)로
저자(author)는 ForeignKey로 선언 한다.
따라서 각 책은 하나의 저자만 가질 수 있지만,
저자는 여러 개의 책들을 가질 수 있다.
몇 가지 살펴봐야할 인수는
null=Ture와 on_delete=models.SET_NULL인수다.
null값을 허용함으로써
어떤 저자도 입력되어있지 않을때
DB에 Null값을 저장하며
on_delete=modles.SET_NULL는
관련된 저자(author) 레코드가 삭제되었을 때
저자의 값을 Null로 설정하게 한다.
또한 Book 레코드를 나타내는
책의 title 필드를 이용해여, __str__()를 정의한다.
마지막 메소드 get_absolute_url()은
이 model의 세부 레코드에 접근하는 데에
사용될 수 있는 URL을 반환한다.
물론 작동하려면 book-detail이라는 이름의 URL을 정의하고
관련 View와 Template를 정의해야 한다.
③ 책 인스턴스(BookInstance) 모델
BookInstance Model은 누군가 빌릴지도 모를 특정한 책의
복사본을 나타낸다.
또한 복사본이 사용 가능한지,
언제 되돌려받을 수 있는지,
출판사(imprint),
버전 세부 사항,
그리고 도서관 안에서 사용하는
책의 고유 id에 대한 정보를 포함하고 있다.
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 | import uuid # Required for unique book instances class BookInstance(models.Model): """Model representing a specific copy of a book (i.e. that can be borrowed from the library).""" id = models.UUIDField(primary_key=True, default=uuid.uuid4, help_text='Unique ID for this particular book across whole library') book = models.ForeignKey('Book', on_delete=models.SET_NULL, null=True) imprint = models.CharField(max_length=200) due_back = models.DateField(null=True, blank=True) LOAN_STATUS = ( ('m', 'Maintenance'), ('o', 'On loan'), ('a', 'Available'), ('r', 'Reserved'), ) status = models.CharField( max_length=1, choices=LOAN_STATUS, blank=True, default='m', help_text='Book availability', ) class Meta: ordering = ['due_back'] def __str__(self): """String for representing the Model object.""" return f'{self.id} ({self.book.title})' | cs |
Model에서 사용된 메소드들에 관한 내용은 아래와 같다.
- ForeignKey : 연관된 Book을 식별하기 위함
- Charfield : 책의 출판사(imprint)을 나타내기 위함
- UUIDField : id 필드가 이 Model의 primary_key로 설정되는데
사용한다. 이 타입의 필드는 고유한 값을 할당한다.
- DateField : due_back(만기일) 날짜에 사용된다.
이 값은 blank나 null이 될 수 있다.
또한 메타데이터는 레코드들이 쿼리에서 반환되었을 때
레코드들을 정렬하기 위해서 사용한다.
- status : choice 및 selection list를 정의하는 CharField이다.
먼저 key, value을 포함한 튜플을 정의하여
choices 인수에 전달한다.
key, value 중 value는 사용자가 선택할 수 있는 값이며
key는 선택되었을 때 실제 저장되는 값이다.
또한 책이 선반에 저장되기 전에는 사용할 수 없으므로
기본 값인 'm'(유지 관리, maintenanace)을 설정했다.
메소드 __str__()은 그것의 고유한 id 그리고
연관된 Book의 제목을 조합하여 BookInstance 객체를 나타낸다.
④ 저자(Author) 모델
이제 대부분의 필드 혹은 메소드가 조금씩 익숙해질 것이다.
Model은 저자(Author)를
이름(first_name), 성(last_name),
생일(date_of_brith),사망일(date_of_death)으로 정의한다.
기본적으로 __str__()는
name을 첫째로 성(last name),
그 다음 이름(first name)이 오는 순서로 리턴한다.
get_absolute_url() 메소드는
각 저자를 나타내기 위한 URL을 가져오기 위해
author-detail URL Mapper를 reverse() 한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | class Author(models.Model): """Model representing an author.""" first_name = models.CharField(max_length=100) last_name = models.CharField(max_length=100) date_of_birth = models.DateField(null=True, blank=True) date_of_death = models.DateField('Died', null=True, blank=True) class Meta: ordering = ['last_name', 'first_name'] def get_absolute_url(self): """Returns the url to access a particular author instance.""" return reverse('author-detail', args=[str(self.id)]) def __str__(self): """String for representing the Model object.""" return f'{self.last_name}, {self.first_name}' | cs |
・데이터베이스 마이그레이션 재실행하기
데이터베이스 마이그레이션 재실행 하기
모든 Model을 작성했다.
cmd창을 열어 가상 서버에 접속한 후
마이그레이션을 실행해보자.
| python manage.py makemigrations python manage.py migrate | cs |
빨간색 박스의 log를 보면
위에서 작성했던
Author, Book, Genre, BookInstance Model이 생성 되는것을 확인할 수있다.