seminar-2020 icon indicating copy to clipboard operation
seminar-2020 copied to clipboard

SeminarSerializer / instructors, participants 문의

Open ghost opened this issue 4 years ago • 3 comments

{
    "id": User id,
    "username": User username,
    "email": User email,
    "first_name": User first_name,
    "last_name": User last_name,
    "last_login": User last_login,
    "date_joined": User date_joined,
    "token": Token key (회원가입과 로그인 경우에만 포함)
    "participant": {
        "id": ParticipantProfile id,
        "university": ParticipantProfile university(string),
        "accepted": ParticipantProfile accepted(bool),
        "seminars": [
            {
                "id": Seminar id,
                "name": Seminar name(string),
                "joined_at": UserSeminar joined_at(datetime),
                "is_active": UserSeminar is_active(bool),
                "dropped_at": UserSeminar dropped_at(datetime, 정보가 없는 경우 null)
            },
            ...
        ] (참여하는 Seminar가 없는 경우 [])
    } (ParticipantProfile이 없는 경우 null),
    "instructor": {
        "id": InstructorProfile id,
        "company": InstructorProfile company(string),
        "year": InstructorProfile year(number, 정보가 없는 경우 null),
        "charge": {
            "id": Seminar id,
            "name": Seminar name(string),
            "joined_at": UserSeminar joined_at(datetime)
        } (담당하는 Seminar가 없는 경우 null)
    } (InstructorProfile이 없는 경우 null)
}

seminar, instructor 필드를 serialize 할 때, 어떻게 복수의 participant 와 instructor 를 가져오고 그것을 serialize 할 수 있는지 궁금합니다.

/

SeminarSerializer 에서

participant = serializers.SerializerMethodField()

로 한 후에,

def get_participant 에서 ParticipantProfile 또는 UserSeminarfilter 를 사용해야 해야하는건가요?

/

위의 방식으로도 가능하다면...

def get_participant(self, seminar):

를 만들어야 하는데...

이 안에서 user 를 어떻게 가져오고 다루어서 해당하는 participant 를 가져와야 하는지 모르겠습니다...

serializer = SeminarSerializer(data=request.data) 하기 전에

request.data['user'] = request.user 를 넣어주어야 하는건가요?

/

(넵... 제가 스스로 해보아서 알아내면 되겠지만... 여기까지 오기에 너무 많은 삽질을 하였고 그만큼 주먹구구식으로 하는 것 같기에 추가 설명을 듣고 싶어서 질문드립니다 ㅠㅠ)

ghost avatar Sep 25 '20 15:09 ghost

SeminarSerializer 에서

participant = serializers.SerializerMethodField()

로 한 후에,

말씀하신 이 부분에서

def get_participant(self,seminar) 로 되어있을텐데

UserSeminar.objects.filter(seminar = seminar) 로 하면 UserSeminar object들을 얻을 수 있겠죠?

그럼 user_seminar_object.user 을 하면 seminar에 연결된 유저 정보를 얻을 수 있고

user_seminar_object.user.participnatprofile(realated_name수정안하셨다는 전제하에)

하면 participantprofile을, instructorprofile도 비슷하게 가져올 수 있을 거에요.

이런 식으로 하셔서 UserSeminar에서 유저를 가져오시면 되는데, 여기서 적절하게 필터를 더 거시면 participant에 해당하는 유저만, instructor에 해당하는 유저만 가져올 수 있을 꺼에요

UserSeminar.objects.filter(seminar=seminar,user__participantprofile_isnull=false)이러면 user중에 participant가 null이 아닌 사람들을 데려 올 수 있을 거구요

물론 한 유저가 복수의 역할을 가질 수 있으니 앞선 쿼리는 예시일 뿐 다른 방법을 사용하시는게 좀 더 알맞아 보입니다.

https://docs.djangoproject.com/en/3.1/ref/models/querysets/ 여기도 참고하세여

eldpswp99 avatar Sep 26 '20 05:09 eldpswp99

답변 정말 감사합니다 ㅠㅠ

ghost avatar Sep 26 '20 19:09 ghost

개인적으로 덧붙이자면, 제가 DB 를 설계할 때 충분히 설계를 고려하지 않아 더욱더 어려웠던 문제였던 것 같습니다.

처음에는 ParticipantProfileInstructorProfileOneToOne 관계이기 때문에 User 가 참여자인지 진행자인지 알려면 user.participantprofileuser.instructorprofile로 접근해야하는 것으로 이해했었습니다.

먼저 답변해주신 분의 말씀대로 UserSeminar.objects.filter(seminar=seminar)Seminar 에 해당되는 UserSeminar 의 오브젝트를 모두 가져온 뒤에 각 오브젝트를 순회하면서 user 를 얻고, 그 user 를 위의 방법으로 판단해서 해결하려고 했었습니다.

하지만, 백엔드장님의 말씀을 듣고 보니 제가 처음에 했던 DB 설계는 참으로 비효율적인 생각이라는 것을 알게 되었습니다. 그저 UserSeminar 의 오븍젝트가 만들어질 때, UserSeminar 와 더불어 role 이라는 필드를 넣어주면 위처럼 지난한 방법을 사용하지 않아도 되었습니다.

UserSeminarroleUserSeminar 의 관계를 바로 알 수 있기 때문입니다. UserSeminar.objects.filter(seminar=seminar, role='participant') 로 세미나의 참가자를 모두 가져올 수 있고 UserSeminar.objects.filter(seminar=seminar, role='instructor') 로 세미나의 진행자를 모두 가져올 수 있습니다.

Seminar 오브젝트가 seminar 로 주어졌다면, seminar.userseminar.filter(role='participant')seminar.userseminar.filter(role='instructor') 세미나의 참가자들과 진행자들을 가져올 수 있을 것입니다.

/

강의 중간에 왜 ManyToMany 를 쓰지 않고 Mapping Table 을 만들어서 쓰는지 그제서야 깊이 이해가 갔습니다.

/

모두 백엔드장님이 강의시간에 언급하신 부분이지만 역시 배우기만 하고 익히지 않으면 안되는 것 같습니다 ㅠㅠ

ghost avatar Sep 27 '20 10:09 ghost