-
Create Room Model and Admin and Core ModelProject using python/Cloning Airbnb 2021. 2. 20. 15:25
core/models.py
DateTimeField와 Meta class
users.User를 제외한 나머지 apps은 core/models.py에 있는 TimeStampedModel() class를 상속할 것이다. TimeStampedModel()은 object가 생성될 때마다 언제 생성되었고 언제 업데이트가 되었는지를 저장한다. DateTimeField는 python datetime.datetime의 인스턴스를 표시하는 함수다 (반면에 DateField는 python의 datetime.date를 표시하는 함수다.). DateTimeField의 auto_now_add는 object가 생성되었을 때의 시간 값을 저장하고, auto_now는 object가 업데이트 된 시간을 저장하는 옵션이다.
models.Model class에는 Meta class가 있다. Meta class는 model class에 여러 가지 옵션을 줄 수가 있다. abstract=True는 abstrat base class로 설정하는 옵션이다. 이 뜻은 database table을 생성하지 않는다는 것이다. TimeStampedModel은 다른 model에 이용되기 때문에 abstract=True를 해줌으로써 새로운 database table을 생성하게 하면 안 된다.
rooms/models.AbstractItem
core_models는 from core import models as core_models로 module을 호출했다.
AbstractItem은 앞으로 생성할 RoomType, Amenity, Facility, HouseRule 등이 상속할 class다.
verbose_name and verbose_name_plural
Room model이 ManyToManyField와 ForeignKey로 받을 model들이다. Meta option으로 verbose_name과 verbose_name_plural을 줬다. verbose_name이란 admin page의 list에서 보여질 이름이다. 만약 verbose_name을 설정하지 않으면 RoomType은 Room types로 보여질 것이다. verbose_name으로 설정을 해줌으로써 Room Type으로 보여진다.
verbose_name_plural도 마찬가지다. Amenitys로 문법에 맞지 않게 뒤에 s가 붙여질 것이다. Amenities로 하고 싶다면 복수를 뜻하는 plural을 뒤에 붙인 verbose_name_plural="Amenities"를 해주자.
아래 스크린샷과 같이 문법에 맞지 이름이 붙어 있다.
Meta class option으로 verbose_name을 주니 이름을 개발자가 정할 수 있다.
rooms/models.Room
CountryField
CountryField()는 pip로 django-country를 설치를 하면 사용할 수 있다.
설치한 third party app은 settings.py에 추가해줘야 한다.
CountryField()를 사용하면 아래 그림과 같이 모든 국가들을 선택할 수 있다. select option form을 제공한다.
validators and MinValueValidator
MinValueValidator는 IntegerField의 최솟값을 정의해준다. 입력된 값이 limit_value보다 낮을 경우 ValidationError를 일으킨다. MinValueValidator 이외에도 MaxValueValidator가 있다.
guests를 -1로 주고 save를 눌렀더니 error가 발생했다. Error 내용은 guests 값을 0이상으로 주라는 것이다.
ForeignKey
ForeignKey는 다른 model을 참조할 때 사용한다. ForeignKey의 첫번째 인자는 pointing을 할 model이다. 여기서 나는 users.User를 ForeignKey로 설정했다. "users"는 app folder의 이름이고 뒤에 User는 models.py 안에 있는 model class 이름이다.
related_name은 "users.User"가 자신을 가리키고 있는 room을 역으로 가리킬 때 사용하는 이름이다. User에는 room이 정의되어 있지 않지만, 자신을 가리키고 있는 room을 "rooms"라는 이름으로 가리킬 수 있다. 예를 들어, User.rooms로 자신을 pointing 하고 있는 room을 retrieve 할 수 있다. related_name option을 추가하지 않았다면, User.room_set으로 Room을 참조할 수 있다.
on_delete option은 자신이 가리키고 있는 model의 object가 삭제되었을 때 현재 이 object를 어떻게 할지를 결정하는 것이다. on_delete=models.CASCADE는 폭포수처럼 host가 삭제되었을 때 이 host가 생성한 이 room도 삭제한다는 뜻이다. 반면에 SET_NULL은 room_type이 삭제되더라도 room이 삭제되지 않는다.
/admin/rooms/room/add page를 보면 이미 생성된 하나의 room type을 선택할 수 있는 것을 볼 수 있다.
ManyToManyField
ForeignKey는 다수의 object가 하나의 object를 가리킨다. 즉, 다대일이다. 예를 들어, 여러 개의 room이 한 명의 host를 가리킨다. 반면에 room은 여러 명의 host를 가리킬 수 없다. 즉 생성된 room object는 단 한 명의 host만 가리킬 수 있고 A라는 host는 여러 개의 room에게 지정당할 수 있다.
ManyToManyField는 다대다다. 하나의 room이 여러 개의 amenity, facility와 house rule을 참조할 수 있다.
Room add page에서 다수의 amenity를 선택할 수 있다.
ForeignKey VS OneToOneField
ForeignKey와 헷갈릴 수도 있는 OneToOneField가 있다. ForeignKey는 앞서 설명한 바와 같이 다대일이다. 반면에 OneToOneField는 이름 그대로 일대일이다. ForeignKey에서는 여러 개의 room이 하나의 host를 가리킬 수 있었지만, OneToOneField는 오직 한 개의 room 만이 한 개의 host를 가리킬 수 있다.
rooms/admin
short_description
list_display로 field 뿐만 아니라 함수도 추가할 수 있다. count_amenities로 하면 list page에서 COUNT AMENITIES로 표시된다. verbose_name처럼 내가 원하는 함수 이름으로 변경하고 싶다면 function.short_description=Amenity Count"로 하면 된다. 그럼 list page 에서 항목의 이름이 Amenity Count로 변경된다.
search_fields
Search_fields는 내가 원하는 object를 찾을 수 있도록 검색 기능을 제공한다. tuple 안에는 django admin이 인식할 수 있는 field를 준다.
field 앞에는 여러 가지 prefix(^, =, @, None)를 줄 수 있다. "^city"는 도시 이름을 검색했을 때 그 이름으로 시작해야 한다. 예를 들어 Seoul이라는 도시를 가지고 있는 room object가 2개가 있다고 하자. 내가 여기서 "eoul"라고 검색을 하면 아무것도 뜨지 않는다. 하지만 "se"만 검색해도 Seoul이 검색될 것이다.
Prefix Lookup ^ stratswith = iexact @ search None icontains raw_id_fields
ForeignKey 같은 경우에는 admin 사이트에서 select 형태로 보여진다. 거기서 하나의 host를 선택하는 것이 편할 수 있지만, host가 수십만 수백만 개일 경우 자신이 원하는 host를 찾는 것은 불가능하다. room type인 경우 많아 보았자 100개가 안 될 것이다. 이 때 필요한 것이 raw_id_fields다. raw_id_fields는 내가 원하는 id 값을 검색으로 바로 찾을 수 있게 form을 바꿔준다. 여기서 "room type"은 추가하지 않고 "host"만 raw_id_fields에 추가했다.
Room type은 select form이지만 Host는 search form이다.
돋보기 모양을 클릭하면 search window가 생긴다. filter나 search 기능을 통해서 원하는 host를 찾을 수가 있다.
filter_horizontal
ManyToManyField에 있는 field를 수평적으로 선택할 수 있는 form을 만들어준다. 밑에 스크린샷을 보자.
참고 자료
- 노마드 코더의 Airbnb 클론 강의
- DateTimeField
- abstract-base-classes
- django-countries
- validator
- Relationship fields(ForeignKey, ManyToManyField, OneToOneField)
- Django Admin Site(Short_description, search_fields, raw_id_fields, filter_horizontal)
소스 코드
github.com/zpskek/airbnb-clone-v3/commit/6e57b0731e6d046471d9be88f259df785857b08f
'Project using python > Cloning Airbnb' 카테고리의 다른 글
Django TabularInline and StackedInline (0) 2021.02.21 Upload media (0) 2021.02.20 Django commands (0) 2021.02.20 Create User Model and Admin Panel (0) 2021.02.19 Django User setting (0) 2021.02.19