๐ฅ Admin Site์ Model ๋ฑ๋ก ๋ฐฉ๋ฒ
๐ฅ Django์ Admin Panel ํ์ฅ์ํค๊ธฐ
๐ฅ Admin Panel Option
๐ฅ Model์ ๋งค์๋๋ฅผ admin์์ ํ์ฉํ๊ธฐ
๐ฅ Timezone Utils ์ฌ์ฉํ๊ธฐ
๐ฅ Save Method ์ค๋ฒ๋ผ์ด๋ฉ
1) ๋ฐ์ฝ๋ ์ดํฐ(@) ์ฌ์ฉ
- ๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ํตํด Model์ ๋ฑ๋กํ๋ฉด ๋ฐ๋ก ์๋ class๋ฅผ ์๋์ผ๋ก ์ฐธ์กฐํ๊ธฐ ๋๋ฌธ์ ์ด๋ค admin class์ธ์ง ๋ช ์ํ ํ์๊ฐ ์์ด์.
- ๐ @admin.register(Model Class)
from django.contrib import admin from . import models @admin.register(models.User) class CustomUserAdmin(admin.ModelAdmin): pass
2) admin.site.register ์ฌ์ฉ
- admin.site.register๋ฅผ ์ด์ฉํ๋ฉด ์ด๋ค admin class๋ฅผ ๋ฑ๋กํ๋์ง ๋ชจ๋ธ๊ณผ ํจ๊ป ๋ช ์ํด์ผํด์.
- ๐ admin.site.register(Model Class, Admin Class)
from django.contrib import admin from . import models class CustomUserAdmin(admin.ModelAdmin): pass admin.site.register(models.User, CustomUserAdmin)
1) Django์ User Admin Panel ์์ ๋ฐ๊ธฐ
- Django์ Admin ๊ฐ์ ธ์ค๊ธฐ
- ๐ from django.contrib.auth.admin import UserAdmin
from django.contrib import admin from django.contrib.auth.admin import UserAdmin # ๐ UserAdmin์ด ์์นํ ๊ณณ from . import models @admin.register(models.User) class CustomUserAdmin(UserAdmin): # ๐ UserAdmin ์์๋ฐ์ """Custom User Admin""" pass
- Django์ Admin์ ์์ํด์ค๋ฉด, list_disply ๋ฐ list_filter๊ฐ ์๋์ผ๋ก ์ธํ ๋์ด ์์ด ๋ํ๋๊ณ , ๊ฒ์์ด ๊ฐ๋ฅํ Search bar๋ ๊ธฐ๋ณธ ์ธํ ๋์ด ์์ด์. ๋ฌผ๋ก Custom๋ ๊ฐ๋ฅํฉ๋๋ค!
2) fieldsets ์ค์
- Admin Panel ๋ด๋ถ๋ก ๋ค์ด๊ฐ๋ฉด, ํ์ฅ์ํจ ํ๋(avatar, gender, bio, birthday ๋ฑ)๋ค์ด ๋ชจ๋ ๋ํ๋์ง ์๋๋ฐ fieldsets์ ํตํด Admin Panel ๋ด๋ถ๋ฅผ Custom ํ ์ ์์ด์!
- fieldsets ํฌ๋งท ํํ๋ ์๋์ ๊ฐ์ต๋๋ค. ๋ํ ๊ธฐ์กด Django Admin์ด ๊ฐ๊ณ ์๋ field๊น์ง ๋ชจ๋ ํ์ํ๊ธฐ ์ํด UserAdmin.fieldsets๊ณผ ์ฐ๋ฆฌ๊ฐ ์์ฑํ fieldsets์ ํฉ์ณ์ค๊ป์:)
from django.contrib import admin from django.contrib.auth.admin import UserAdmin from . import models # Register your models here. @admin.register(models.User) class CustomUserAdmin(UserAdmin): """Custom User Admin""" fieldsets = UserAdmin.fieldsets + ( ( "Custom Profile", # ๐ ๋ถ๋ฅ title { "fields": ( "avatar", "gender", "bio", "birthdate", "language", "currency", "superhost", ) }, ), )
1) list_diplsy ์ต์
- list_diplsy์ ํํ๋ก ํ๋๋ช ์ ์ ๋ ฅํ๋ฉด Admin Panel์ ๋ํ๋ผ ํ๋๊ฐ์ ์ง์ ํ ์ ์์ด์.
- ๐ list_display = ("ํ๋๋ช 1", "ํ๋๋ช 2", "ํ๋๋ช 3", )
- ๋จ, ManyToManyField๋ list_display์ ํ๋๊ฐ์ผ๋ก ์ฌ์ฉํ ์ ์๊ธฐ ๋๋ฌธ์ Admin Panel์ ๋ํ๋ด๊ณ ์ํ๋ค๋ฉด ๋งค์๋๋ฅผ ์์ฑํ์ฌ list_display์ ๋ฃ์ด์ค๋๋ค.
- ์ฌ๊ธฐ์ self์ obj๋ฅผ ์ ๋ฌํ๋๋ฐ์,, self๋ Admin Class์ธ RoomAdmin ๊ฐ๋ฅดํค๊ณ , obj๋ admin์ ํ์ฌ row๋ฅผ ์๋ฏธํฉ๋๋ค.
- [๋งค์๋๋ช ].short_description๋ก Admin Panel์ ์ถ๋ ฅ๋ ํ๋ ์ด๋ฆ์ ์์ ํ ์ ์์ด์!
@admin.register(models.Room) class RoomAdmin(admin.ModelAdmin): """Room Admin Dfinition""" list_display = ( "name", "country", "city", "price", "guests", "beds", "bedrooms", "baths", "check_out", "check_in", "instant_book", "count_amenities", ) def count_amenities(self, obj): return obj.amenities.count() # ๐ ํ์ฌ row์ amenities๋ฅผ ๊ฐฏ์๋ฅผ ๋ฐํ count_amenities.short_description = "amenities" # ๐ count_amenities์ amenities๋ก ๋ณ๊ฒฝ
2) list_filter ์ต์
- list_filter์ ์ฐ์ธก์ ํํฐ ๊ธฐ๋ฅ์ ์ถ๊ฐ์์ผ ์ค๋๋ค.
- ๐ list_filter = ("ํ๋๋ช 1", "ํ๋๋ช 2", "ํ๋๋ช 3", )
@admin.register(models.Room) class RoomAdmin(admin.ModelAdmin): """Room Admin Dfinition""" list_filter = ( "instant_book", "host__superhost", "room_type", "amenities", "facilities", "house_rule", "city", "country", )
3) search_filter ์ต์
- search_filter๋ฅผ ์ฌ์ฉํ๋ฉด search bar๋ฅผ ๊ฐํธํ๊ฒ ๋ง๋ค ์ ์์ด์.
- ๐ search_filter = ("ํ๋๋ช 1", "ํ๋๋ช 2", "ํ๋๋ช 3", )
- search_filter๋ default๋ก icontains๋ฐฉ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ฐพ์์ฃผ๋ฉฐ, Prefix๋ฅผ ์ฌ์ฉํ์ฌ ๊ฒ์์ด๋ฅผ ์ด๋ค ๊ธฐ์ค์ผ๋ก ์ฐพ์์ง ๊ฒฐ์ ํ ์ ์์ด์.
- None(icontains) : ๋๊ฐํ ๊ธฐ์ค(๋์๋ฌธ์ ๊ตฌ๋ณ ์ํจ)์ผ๋ก ์ ๋ ฅํ ๊ฒ์์ด๊ฐ ํฌํจ๋ object๋ฅผ ๋ฐํ
- ^(startswith) : ^์ต์ ์ ๊ฐ์ด ๋ฃ์ด์ฃผ๋ฉด, ์์ฒญํ ๊ฒ์์ด๋ก ์์๋๋ object๋ฅผ ๋ฐํ
- =(iexact) : ์์ฒญํ ๊ฒ์์ด์ ์ ํํ ์ผ์นํ๋ object๋ฅผ ๋ฐํ
- ์์ฑ๋ ํ๋ ์ค ForeignKey๊ฐ ์๋ค๋ฉด, ๋๋ธ ์ธ๋์ค์ฝ์ด(
__
)๋ฅผ ํตํด ์ฐธ์กฐํ๋ ๋์์ ๋ชจ๋ธ๋ก ์ ๊ทผ์ด ๊ฐ๋ฅํฉ๋๋ค. ์ด๋ฐ ๋ฌธ๋ฒ ์คํ์ผ์ list_disply, list_filter ๋ฑ์์๋ ์ฌ์ฉ ๊ฐ๋ฅํด์!
- ๐ search_fields = ("^host__username", )
@admin.register(models.Room) class RoomAdmin(admin.ModelAdmin): """Room Admin Dfinition""" list_display = ( "name", "country", "city", "price", ) search_fields = ( "city", "^host__username", "=price", )
4) filter_horizontal ์ต์
- filter_horizontal ์ต์ ์ ManyToManyField์ Admin Panel ๋ด๋ถ์ ์ ์ฉ๋๋ ๊ธฐ๋ฅ์ด์์.
- filter_horizontal ์ต์ ์ ์ฌ์ฉํ๋ฉด, ํ๋์ ์คํ์ผ์ ํธ๋ฆฌํ๊ฒ ๋ณ๊ฒฝํด์ค์.
@admin.register(models.Room) class RoomAdmin(admin.ModelAdmin): """Room Admin Dfinition""" filter_horizontal = ( "amenities", "facilities", "house_rule", )
๐ default
๐ filter_horizontal
5) ordering ์ต์
- ordering ์ต์ ์ ํ๋๊ฐ์ ์ง์ ํ๋ฉด, Admin Panel์ ์ ๋ ฌ ๋ฒํผ(์ผ๊ฐํ ๋ฒํผ)์ ์์ฑํด์ค๋๋ค.
@admin.register(models.Room) class RoomAdmin(admin.ModelAdmin): """Room Admin Dfinition""" ordering = ( "name", "price", )
6) raw_id_fields ์ต์
- Admin Panel ๋ด๋ถ๋ก ๋ค์ด๊ฐ๋ณผ ๊น์? ์ฌ์ฉ์๊ฐ ๋์ด๋๋ค๋ฉด, ํ๋๊ฐ์ด ๋ง์์ ธ ์คํฌ๋กค์ ์๋ฐ์ผ๋ก ๋ถํธ์ ์ ๋ฐํฉ๋๋ค:)
- ์ด๋ด ๊ฒฝ์ฐ, raw_id_fields๋ก ํด๋น ํ๋๋ฅผ ์ง์ ํด์ฃผ๋ฉด ํ์ ์ฐฝ์ ๋ง๋ค์ด์ค์. ์ํ๋ ๊ฐ์ ์ฐพ๊ธฐ ์ฌ์์ง๋๋ค!
@admin.register(models.Room) class RoomAdmin(admin.ModelAdmin): """Room Admin Dfinition""" raw_id_fields = ("host",)
1) reviews/models.py
- ๊ฐ Review Object์ ํ์ ์ ํ๊ท ์ ๊ตฌํด์ ๋ฐํํ๋ ๋งค์๋ ์์ฑํ์ด์.
- ๊ฐ ๊ฐ์ค์ ์ ์ : accuracy, communication, cleanliness, location, check_in, value
- ํด๋น ๋งค์๋๋ช ์ list_display์ ์ถ๊ฐ๋งํ๋ฉด Admin Panel์์ ๊ฐ Reivew์ ๋ํ ํ์ ์ ๋ณด๋ฅผ ๋ณผ ์ ์๋ต๋๋ค.
- short_description์ admin.py ๋ฐ models.py ๋ชจ๋ ์ฌ์ฉ ๊ฐ๋ฅํฉ๋๋ค.
- ๐ rating_average.short_description = "Avg."
from django.db import models from core import models as core_models # Create your models here. class Review(core_models.TimeStampedModel): """Review Model Definition""" review = models.TextField() accuracy = models.IntegerField() communication = models.IntegerField() cleanliness = models.IntegerField() location = models.IntegerField() check_in = models.IntegerField() value = models.IntegerField() user = models.ForeignKey( "users.User", related_name="reviews", on_delete=models.CASCADE ) room = models.ForeignKey( "rooms.Room", related_name="reviews", on_delete=models.CASCADE ) def __str__(self): return f"{self.review} - {self.room}" def rating_average(self): avg = ( self.accuracy + self.communication + self.cleanliness + self.location + self.check_in + self.value ) / 6 return round(avg, 2) # ๐ ์์์ 2์งธ์๋ฆฌ๊น์ง ๋ํ๋ผ๊ฑฐ์์:) rating_average.short_description = "Avg."
2) reviews.admin.py
__str__
๋งค์ง๋งค์๊ฐ list_display์ ๋ฎ์ด์์ด์ ธ Admin Panel์ ๋ณด์ด์ง ์์ ๋๋ ๋นํฉํ์ง ๋ง๊ณ ,, "list_display"์__str__
๋ฅผ ์ถ๊ฐํด์ฃผ๋ฉด ๋์!from django.contrib import admin from . import models # Register your models here. @admin.register(models.Review) class ReviewAdmin(admin.ModelAdmin): """Review Admin Definition""" list_display = ( "__str__", "rating_average", )
3) rooms/models.py
- ๊ฐ ๊ฐ์ค์ ์ฐธ์กฐํ๋ ๋ชจ๋ Review ์ ๋ณด๋ฅผ all_reviews์ ๋ด์์ด์. "self.reviews.all()"์์ reviews๋ ์ด๋์ ์์๊น์? roomํ๋(reviews/models.py)์ related_name ๊ฐ์ ๋๋ค.
- ๐ all_reviews = self.reviews.all()
- ์ด์ all_reviews์ ๊ฐ ๊ฐ์ค์ ๊ฐ๋ฅดํค๋ ๋ชจ๋ Review๋ฅผ ๋ด์๋์์ด์. rating_average() ๋งค์๋๋ฅผ ํตํด ํ์ ๊ฐ์ ๋ชจ๋ ํฉํ ๋ค, all_reviews์ ๊ธธ์ด๋งํผ ๋๋ ๋ฐํํ๋ฉด ๊ฐ ๊ฐ์ค์ ๋ํ ํ์ ์ ๋ณด ์ ๊ณตํด์ค์.
- ๐ all_rating += review.rating_average()
class Room(core_models.TimeStampedModel): """Room Model Definifion""" def total_rating(self): all_reviews = self.reviews.all() all_rating = 0 if len(all_reviews) != 0: for review in all_reviews: all_rating += review.rating_average() # ๐ ๋งค์๋๋ ์ ๊ทผ ๊ฐ๋ฅ return all_rating / len(all_reviews) else: # ๐ Review๊ฐ 1๊ฐ๋ ์์ฑ๋์ง ์์ ๊ฐ์ค์ด ์กด์ฌํ ๊ฒฝ์ฐ๋ฅผ ๋๋นํ ๋ฐฉ์ด์ฝ๋์์:) return 0 total_rating.short_description = "rating"
1) Timezone Utils
- Python์ Time ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ง ์๊ณ , TimeZone์ ์ฌ์ฉํ๋ ์ด์ ๋ settgins.py์์ ์ค์ ๋ TimeZone์ด Django์ ์๋ฒ์ ์๊ฐ์ ๊ด์ฅํ๊ณ ์๊ธฐ ๋๋ฌธ์ด์์.
- ๐ from django.utils import timezone
- ๋ฐํ๊ฐ์ Boolean ์์ด์ฝ์ผ๋ก ํ์ํ๋ ๋ฐฉ๋ฒ
- ๐ in_progress.boolean = True
from django.db import models from django.utils import timezone # ๐ timezone util์ ๊ฐ์ ธ์ค๊ธฐ from core import models as core_models # Create your models here. class Reservation(core_models.TimeStampedModel): """Reservation Model Definition""" STATUS_PENDING = "pending" STATUS_CONFIRMED = "confirmed" STATUS_CANCELED = "canceled" STATUS_CHOICES = ( (STATUS_PENDING, "Pending"), (STATUS_CONFIRMED, "Confirmed"), (STATUS_CANCELED, "Canceled"), ) status = models.CharField( max_length=12, choices=STATUS_CHOICES, default=STATUS_PENDING ) check_in = models.DateField() check_out = models.DateField() guest = models.ForeignKey( "users.User", related_name="reservations", on_delete=models.CASCADE ) room = models.ForeignKey( "rooms.Room", related_name="reservations", on_delete=models.CASCADE ) def __str__(self): return f"{self.room} - {self.check_in}" def in_progress(self): now = timezone.now().date() # ๐ ํ์ฌ ์๋ฒ ๋ ์ง return now >= self.check_in and now <= self.check_out in_progress.boolean = True # ๐ return๊ฐ์ True, False๊ฐ ์๋ ์์ด์ฝ์ผ๋ก ๋ํ๋ด์ค์. def is_finished(self): now = timezone.now().date() # ๐ ํ์ฌ ์๋ฒ ๋ ์ง return now > self.check_out is_finished.boolean = True # ๐ return๊ฐ์ True, False๊ฐ ์๋ ์์ด์ฝ์ผ๋ก ๋ํ๋ด์ค์.
1) rooms.models.py
- form์ ์ ๋ ฅํ ์ ๋ณด๊ฐ DB์ ํด๋น ํ๋๋ก ์ ์ฅ๋๋ ๊ฒ์ด save() ๋งค์๋์ ์ญํ ์ด์์. ์ฆ, Save Event๋ฅผ ๊ฐ๋ก์ฑ๋ค๋ ๊ฒ์ ๊ธฐ์กด์ save() ๋งค์๋๋ฅผ ์ค๋ฒ๋ผ์ด๋ฉํ์ฌ ๊ฐ์ ๋ค๋ฃฌ ๋ค, super()๋ฅผ ํตํด save()์ ๋ณธ๋ ๊ธฐ๋ฅ์ ์คํ์ํค๋ ๊ฒ ์ ๋๋ค. ์ ์ฅ๋๊ธฐ ์ ์ ์ ์ ๊ฐ์ ๊ฐ๋ก์ฑ์ ์กฐ์น๋ฅผ ์ทจํ๊ณ ์ ์ฅ์ํค๋ ๊ฑฐ์ฃ !
from django.db import models from django_countries.fields import CountryField from core import models as core_models # Create your models here. class Room(core_models.TimeStampedModel): """Room Model Definifion""" ... ... city = models.CharField(max_length=80) ... ... def save(self, *args, **kwargs): self.city = str.capitalize(self.city) # ๐ ์๊ธ์๋ฅผ ๋๋ถ์๋ก ๋ฐ๊พธ๊ณ super().save(*args, **kwargs) # ๐ ์๋ save ๋งค์๋๋ฅผ ์คํ