Serializer_응용 - KEEMSY/DRF_AFTER_CLASS GitHub Wiki
Serializer 응용
역참조
외래키를 사용해 참조하는 object를 역으로 찾는다.
- 외래키 지정 시
related_name
설정을 통해 역참조 시 사용될 이름을 지정한다. related_name
을 설정하지 않는다면 기본적으로tablename_set
형태로 지정된다.
user_profile.hobby
-> 정참조
hobby.userprofile_set
-> 역참조
foreignkey, many-to-many
- 한 object를 여러 object에서 참조 가능하다.(한개의 hobby object를 여러개의 userprofile에서 참조 가능하다.
- 특정 hobby object에서 userprofile_set을 사용하여 역참조 할 경우, 데이터는 object가 아닌 queryset으로 보여진다.
# Hobby model에서 무작위 object를 지정
hobby = HobbyModel.objects.all().order_by("?").first()
# userprofile_set은 many to many기 때문에 queryset 형태
# 아래와 같이 사용 할 경우 hobby object를 참조하는 모든 userprofile을 return
# .all()을 붙여주지 않으면 user.UserProfile.None와 같은 형태로 return됨
hobby_users = hobby.userprofile_set.all()
# queryset 형태기 때문에 필요에 따라 특정 filter를 걸어 줄 수도 있다.
hobby_users = hobby.userprofile_set.filter(field=value)
역참조를 활용한 같은 취미를 가진 사람을 찾는 코드
def get(self, request):
user = request.user
hobbys = user.userprofile.hobby.all()
for hobby in hobbys:
# exclde : 매칭 된 쿼리만 제외, filter와 반대
# annotate : 필드 이름을 변경해주기 위해 사용, 이외에도 원하는 필드를 추가하는 등 다양하게 활용 가능
# values / values_list : 지정한 필드만 리턴 할 수 있음. values는 dict로 return, values_list는 tuple로 ruturn
# F() : 객체에 해당되는 쿼리를 생성함
hobby_members = hobby.userprofile_set.exclude(user=user).annotate(username=F('user__username')).values_list('username', flat=True)
hobby_members = list(hobby_members)
print(f"hobby : {hobby.name} / hobby members : {hobby_members}")
# result print
"""
hobby : 산책 / hobby members : ['user1']
hobby : 음악감상 / hobby members : ['user1', 'user2']
hobby : 스쿠버다이빙 / hobby members : ['user2']
hobby : 여행 / hobby members : ['user2']
"""