최종프로젝트에서 마이페이지에 해당하는 로직을 작성해보았는데,
# workshops/serializers.py
class WorkshopListSerializer(serializers.ModelSerializer): # 워크샵 전체 목록 조회
category = serializers.SerializerMethodField()
location = serializers.SerializerMethodField()
def get_category(self, obj):
return obj.category.category
def get_location(self, obj):
return obj.location.district
class Meta:
model = Workshop
fields = ('title', 'content', 'workshop_image', 'category', 'location',)
class WorkshopSerializer(serializers.ModelSerializer): # 특정 워크샵 상세 조회
host = serializers.SerializerMethodField()
likes_count = serializers.SerializerMethodField()
participant_count = serializers.SerializerMethodField()
category = serializers.SerializerMethodField()
location = serializers.SerializerMethodField()
review_workshop = ReviewSerializer(many=True)
def get_host(self, obj):
return obj.host.nickname
def get_category(self, obj):
return obj.category.category
def get_location(self, obj):
return obj.location.district
def get_likes_count(self, obj):
return obj.likes.count()
def get_participant_count(self, obj):
return obj.participant.count()
class Meta:
model = Workshop
fields = ('title', 'content', 'workshop_image', 'category', 'location', 'address', 'host', 'amount', 'date', 'created_at', 'max_client', 'participant_count', 'likes_count', 'review_workshop',)
class SelectedHobbySerializer(serializers.ModelSerializer): # 마이페이지 - 내가 선택한 취미
hobby = serializers.StringRelatedField(many=True)
class Meta:
model = User
fields = ('hobby',)
class AppliedWorkshopSerializer(serializers.ModelSerializer): # 마이페이지 - 신청 워크샵
member = WorkshopListSerializer(many=True)
class Meta:
model = User
fields = ('member',) # (이후 변경 예정)
class CreatedWorkshopSerializer(serializers.ModelSerializer): # 마이페이지 - 생성 워크샵
workshop_host = WorkshopListSerializer(many=True)
class Meta:
model = User
fields = ('workshop_host',) # (이후 변경 예정)
마이페이지에 해당하는 아래 세 개의 클래스는 기본적으로 User 모델을 기반으로 하되, 불러오고자 하는 데이터의 내용을 일부 인스턴스로 추가한 점을 확인할 수 있다.(hobby, member, workshop_host)
여기서 조금 주의할 점은, 첫번째 "내가 선택한 취미"에서 hobby는 'workshops.Hobby' 모델과 M:M 관계로 연결되어 있어 역참조로 헷갈릴 수 있으나, Hobby에 User 모델과 연결된 Foreignkey가 없기 때문에 정참조의 관계로 볼 수 있다.
(이 단순한 것을 몰라 몇시간을 머리 싸맨게 좀 허무했다. 이걸 계기로 데이터베이스에 대해 제대로 공부해야 할 필요성을 절감했고 다행히 친절한 팀원분들이 잘 설명해 주셔서 그나마 이해한 것 같다.)
따라서 related_name 없이 hobby라고 명명해주면 되지만, 아래 두 클래스(신청워크샵, 생성워크샵)의 경우 User모델을 기반으로 하지만 workshopListSerializser를 활용하고 그 안에 Workshop 모델이 적용되므로, 우선 User와 Workshop 의 상관관계를 파악해야 한다. User: Workshop = 1:M 이므로 Workshop 모델을 User 모델로 가져오기 위해서는 반드시 역참조 방식을 활용해야 하며 그 중 한 예로 related_name을 적어주면 된다. (아래 workshops/models.py 참고)
# workshops/models.py
class Hobby(models.Model):
category = models.CharField(max_length=10)
def __str__(self):
return str(self.category)
class Location(models.Model):
district = models.CharField(max_length=20)
def __str__(self):
return str(self.district)
class Workshop(models.Model):
category = models.ForeignKey(Hobby, on_delete=models.CASCADE, related_name='workshop_category')
host = models.ForeignKey(User, on_delete=models.CASCADE, related_name='workshop_host')
date = models.DateTimeField()
location = models.ForeignKey(Location, on_delete=models.CASCADE)
address = models.CharField(max_length=20)
title = models.CharField(max_length=20)
content = models.TextField(max_length=500)
workshop_image = models.ImageField(upload_to='workshop/')
max_client = models.IntegerField()
amount = models.DecimalField(decimal_places=0, max_digits=10000000000000000)
created_at = models.DateTimeField(auto_now_add=True)
participant = models.ManyToManyField(User, related_name='member', symmetrical=False, blank=True)
likes = models.ManyToManyField(User, related_name='workshop_likes')
def __str__(self):
return self.title
class Review(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='reveiw_user')
workshop = models.ForeignKey(Workshop, on_delete=models.CASCADE, related_name='review_workshop')
content = models.TextField(max_length=50)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return str(self.content)
User 모델에 대한 정보는 아래와 같다.
# users/models.py
# 사용자모델
class User(AbstractBaseUser):
email = models.EmailField("이메일" , max_length=255, unique=True)
nickname = models.CharField("닉네임", max_length=15, unique=True)
hobby = models.ManyToManyField('workshops.Hobby')
profile_image = models.ImageField(blank=True)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
objects = UserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['nickname']
def __str__(self):
return self.email
def has_perm(self, perm, obj=None):
"Does the user have a specific permission?"
# Simplest possible answer: Yes, always
return True
def has_module_perms(self, app_label):
"Does the user have permissions to view the app `app_label`?"
# Simplest possible answer: Yes, always
return True
@property
def is_staff(self):
"Is the user a member of staff?"
# Simplest possible answer: All admins are staff
return self.is_admin'스파르타코딩 AI웹개발 3기' 카테고리의 다른 글
| 내일배움캠프_TIL_2022.12.06 (0) | 2022.12.07 |
|---|---|
| 내일배움캠프_WIL_2022.12.04 (0) | 2022.12.06 |
| 내일배움캠프_TIL_2022.12.02 (0) | 2022.12.06 |
| A6조 최종프로젝트 SA 제출 (22.12.01) (0) | 2022.12.01 |
| 내일배움캠프_TIL_2022.11.30 (0) | 2022.12.01 |