Admin Methods
1) list_display에 'total_amenities'를 추가
2) rooms > models.py에 없는 내용이므로 에러 발생
3) rooms > admin.py에서 메서드로 추가 가능
4) rooms > models.py에서도 추가 가능
ForeignKey Filter
Reverse Accessor(역방향 접근자)
oreignKey, OneToOneField, ManyToManyField 등을 사용할 때 자동으로 생성되는 속성
모델 간의 관계를 정의할 때 두 모델 사이의 역방향 관계에 접근할 수 있게 해주는 개념
외래 키나 다대다 관계를 통해 연결된 관련 객체들을 쉽게 조회할 수 있음
(해당 모델의 인스턴스에서 관련된 다른 모델의 인스턴스에 접근할 수 있다)
ex. user_1은 여러개의 사진을 업로드 할 수 있다
<-> user_1의 profile에서 user_1이 업로드한 모든 사진을 볼 수 있다
ex. room_1에 얼마나 많은 review가 만들어졌는지 알 수 있다
<-> 그 중 한 review의 user가 어떤 review들을 작성했는지 알 수 있다
"Reverse is everywhere."
ForeignKey를 이용한 필터링
특정 room_1을 위해 만들어진 review가 얼마나 있는지
하나의 user가 생성한 room이 얼마나 있는지
>>> from rooms.models import Room
>>> room_1 = Room.objects.get(pk=1)
>>> room_1
<Room: Beautiful House>
>>> room_1.price
20
>>> room_1.owner
<User: busybee>
>>> room_1.owner.username
'busybee'
# room_1 owner의 username을 검색
>>> Room.objects.filter(owner__username="busybee")
<QuerySet [<Room: Beautiful House>]>
# owner의 username으로 필터링
>>> Room.objects.filter(owner__username__startswith="b")
<QuerySet [<Room: Beautiful House>]>
review.user : 해당 review를 작성한 user 정보
user.reviews : 해당 user가 작성한 review 정보
🤜 미션: 한 user가 만든 모든 room 정보 조회하기 🤛
1) room에서 필터링: 반복적으로 사용해야한다
2) user 관점에서 바라보기: 위 필터링 기능들은 이미 우리 user모델에 built-in 되어있다
>>> from users.models import User
>>> me = User.objects.get(pk=1)
>>> me
<User: busybee>
>>> dir(me)
['CurrencyChoices', 'DoesNotExist', 'EMAIL_FIELD', 'GenderChoices', 'LanguageChoices', 'Meta', 'MultipleObjectsReturned', 'REQUIRED_FIELDS', 'USERNAME_FIELD', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_check_column_name_clashes', '_check_constraints', '_check_db_table_comment', '_check_default_pk', '_check_field_name_clashes', '_check_fields', '_check_id_field', '_check_index_together', '_check_indexes', '_check_local_fields', '_check_long_column_names', '_check_m2m_through_same_relationship', '_check_managers', '_check_model', '_check_model_name_db_lookup_clashes', '_check_ordering', '_check_property_name_related_field_accessor_clashes', '_check_single_primary_key', '_check_swappable', '_check_unique_together', '_do_insert', '_do_update', '_get_FIELD_display', '_get_expr_references', '_get_field_value_map', '_get_next_or_previous_by_FIELD', '_get_next_or_previous_in_order', '_get_pk_val', '_get_session_auth_hash', '_get_unique_checks', '_meta', '_password', '_perform_date_checks', '_perform_unique_checks', '_prepare_related_fields_for_save', '_save_parents', '_save_table', '_set_pk_val', '_state', '_validate_force_insert', 'acheck_password', 'adelete', 'arefresh_from_db', 'asave', 'avatar', 'booking_set', 'chattingroom_set', 'check', 'check_password', 'clean', 'clean_fields', 'currency', 'date_error_message', 'date_joined', 'delete', 'email', 'email_user', 'experience_set', 'first_name', 'from_db', 'full_clean', 'gender', 'get_all_permissions', 'get_constraints', 'get_currency_display', 'get_deferred_fields', 'get_email_field_name', 'get_full_name', 'get_gender_display', 'get_group_permissions', 'get_language_display', 'get_next_by_date_joined', 'get_previous_by_date_joined', 'get_session_auth_fallback_hash', 'get_session_auth_hash', 'get_short_name', 'get_user_permissions', 'get_username', 'groups', 'has_module_perms', 'has_perm', 'has_perms', 'has_usable_password', 'id', 'is_active', 'is_anonymous', 'is_authenticated', 'is_host', 'is_staff', 'is_superuser', 'language', 'last_login',
'last_name', 'logentry_set', 'message_set', 'name', 'natural_key', 'normalize_username', 'objects', 'password', 'pk', 'prepare_database_save', 'refresh_from_db', 'review_set', 'room_set', 'save', 'save_base', 'serializable_value', 'set_password', 'set_unusable_password', 'unique_error_message', 'user_permissions', 'username', 'username_validator', 'validate_constraints', 'validate_unique', 'wishlist_set']
>>> me.room_set.all()
<QuerySet [<Room: Beautiful House>]>
dir(me): 'me'가 가진 속성, 메서드를 출력 'ㅇㅇ_set':'me'의 reverse accesor
ex. rooms 모델은 category에 대해 foreignkey를 가지고 있음: category 모델은 room_set을 받는다
Reverse Accessors의 이름 변경하기
모델 A가 모델 B의 foreign key를 가지고 있으면: 모델 B는 저절로 '모델 A_set'를 받는다
이때 reverse accessor의 이름을 임의로 변경할 수 있다
ex. room_set -> rooms
✍️ 방법 ✍️
모델 A에서 related_name을 추가한다rooms > models.py
owner = models.ForeignKey("users.User", on_delete=models.CASCADE)
owner = models.ForeignKey("users.User", on_delete=models.CASCADE, related_name="rooms")
이제 user는 'room_set'이 아닌 'rooms'를 갖는다
amenities, category에서도 변경해준다
amenities = models.ManyToManyField("rooms.Amenity", related_name='rooms')
category = models.ForeignKey("categories.Category", null=True, blank=True, on_delete=models.SET_NULL, related_name='rooms')
>>> from users.models import User
>>> me = User.objects.get(pk=1)
>>> me
<User: busybee>
>>> me.rooms.all()
<QuerySet [<Room: Beautiful House>]>
이제 rooms로 작업할 수 있다
foreign key/many to many를 갖는 나머지 모델들도 위와 같이 수정할 수 있다
Recap
하나의 Review는 하나의 User에 속한다
하나의 Review는 하나의 Room에 속한다
하나의 User는??
room_set으로 확인할 수 있다
foreign key를 가지고 있는 모델은 'ㅇㅇㅇ_set'이 저절로 생성된다
'ㅇㅇㅇ_set'의 이름을 변경할 수 있다
'airbnb clone coding' 카테고리의 다른 글
[Django] 8_2. Power Admin: Admin Actions / Custom Filters (0) | 2024.07.16 |
---|---|
[Django] 8_1. Power Admin: Methods / Search Fields (0) | 2024.07.15 |
[Django] 7_1. ORM Query Sets: filter, get, create, delete (0) | 2024.07.13 |
[Django] 6_4. Models and Admin: Reviews / Wish Lists / Bookings / Medias / Messages (0) | 2024.07.13 |
[Django] 6_3. Models and Admin: Category (0) | 2024.07.12 |