- TIL. 최종프로젝트(3) 퀴즈 제너레이터 목차
[오늘 한일]
- 퀴즈 신고하기 기능 작성
- 퀴즈 제공할때 10개 뽑는 기능 작성
팀 진행
- 프론트엔드 > 퀴즈 기능까지 작성
- 데이터 크롤링 기능 작성
- 소셜 로그인 진행중
[오늘 논의한 내용]
- 아침 회의: 기능 개발 계속 진행
- 회원가입 기능 잘안됨 > 시리얼라이저 수정필요
- 소셜로그인 진행중, 데이터 크롤링 진행중
- 진행하며 의논한 부분
- 구글연동 로그인이 원할이 안됨.
- 저녁회의: 기능적으로 추가할 방향
- 퀴즈 유형
- 웹토큰을 이용한 실시간 겨루기
- 주간고사, 경시대회 > 보상과 연결
- 코스별 퀴즈
- 퀴즈 제공, 보상, 랭킹에 대한 논의
- 기술적 달성에 대한 논의
- 스코프가 작다. 알고 있는 기술로만 작성할수 있다. > 웹토큰, ci/cd. 가능한대로 기술 적용.
- 소셜 로그인 완성도에 대한 논의
- 퀴즈 유형
서면 피드백 + 튜터님 피드백에서,
기술 사용에 대해서 스코프가 작아서 아쉽다는 말씀이 있으셨다.
처음 정한 아이템이 다소 간단하다보니 그런것 같다.
팀과 함께 재차 논의해보았다.
아이템은 그대로 가되, 가능한한 기술들을 적용해보기로 했다.
내용이 단순하지만 재미는 있을거 같다는 기대도 있었다.
우리 의도 또한 그렇다.
가장 재미있고 계속 찾게되는 서비스를 만들고 싶다.
최대한 알차게 만들어 봐야겠다.
웹소켓, 소셜로그인 부분에서 완성도를 높일 여지가 많아 보인다.
[오늘 배운점]
DRF
<serializer 다시 제대로 활용하기>
어저께 퀴즈 보기 뷰에 초기화 메서드를 오버라이드해서 커스텀 한 부분이 있었다.
오늘 신고하기 기능을 작성하면서 보니, 어제 그럴 필요가 없었다.
serializer에서 입력이 기대되지 않는 필드는 필드를 포함시키지 않고,
serializer를 저장할때 필요한 값을 추가해주면 된다.
이쪽이 오히려 배웠던 대로이고 기본적인 serializer활용 모습에 가깝다.
#시리얼라이저
class OptionSerializer(serializers.ModelSerializer):
(중략)
fields = (
"content",
"is_answer",
)
#퀴즈보기뷰
def post(self, request):
"""퀴즈 뷰 post"""
opt_serializer = OptionSerializer(data=request.data["options"], many=True)
if opt_serializer.is_valid():
opt_serializer.save(quiz_id=save_quiz.id)
즉, 위처럼 작성하면 된다.
이렇게 바꿔줄수 있었다.
(반면, serializer에서 id가 빠지게 되었는데,
만약 다른 기능에서 id가 포함된 option serializer가 필요하다면,
그런 형태의 serializer를 하나 더 만들어줄수 있다.
이걸 하나로 뭉치기 위해 기교를 부릴수도 있겠지만,
그럴필요없이 기능별로 serializer가 나눠지는건 나쁘게 보이지 않는다)
<random모듈>
전체 퀴즈중에 10개를 랜덤으로 뽑아서 퀴즈를 제공한다.
그러기 위해 우선 랜덤 모듈로 코드를 작성해봤다.
class QuizGenerator():
def generate():
quiz_count = Quiz.objects.count()
generate_count = 10
quiz_ids = random.sample(range(1, quiz_count), k=generate_count)
return Quiz.objects.filter(id__in=quiz_ids)
위처럼, 먼저 퀴즈의 전체 개수와, 만들 퀴즈 개수를 구한다.
많은 퀴즈들 중에 10개만 랜덤으로 뽑는데,
적합한 random모듈의 함수가 무엇일지 천천히 찾아봤다.
한개 요소를 뽑는 randrange, randint는 적합하지 않다.
randchoice는 리스트에서 뽑긴하는데 역시 한개를 뽑는다.
적합해 보이는 randchoices가 있었다.
randchoices(list, k=숫자)
주어진 리스트에서 k=숫자 만큼을 뽑아서 리스트를 반환한다.
다만, randchoices는 중복을 허용한다.
전체리스트에서 선택을 반복하는것이다.
가장 적합한 것은 randsample이였다.
randsample(list, k=숫자)
주어진 리스트에서 숫자만큼 골라내어 리스트를 반환하며 요소가 중복되지 않는다.
결론, 이렇게 찾아보며 random 모듈에 대해 다양하게 알게 되었다.
https://stackabuse.com/how-to-randomly-select-elements-from-a-list-in-python/ 참고한 자료
<ORM 필터링 연산자>
위 코드에서 리턴 부분을 보면 모델.object.filter에 인자로 특이한 작성법이 적혀있다.
__in이다.
이렇게 구분자가 될 키뒤에 언더바 두개를 붙이고 적어주는 부분을 ORM필터링 연산자라고 한다.
내가 본적있는 연산자로는 __gte가 있다.
그냥 id를 적었다면 값인 quiz_ids는 정확히 타겟 값을 지칭해야 할것이다.
하지만 quiz_ids는 id값들이 담긴 리스트이다.
__in을 붙임으로써 값으로 이터러블한 데이터를 기대하게 되고,
리스트에 담긴 값에 해당하는 오브젝트들을 모두 가져올수 있도록 동작한다.
생각보다 스마트하다.
https://stackoverflow.com/questions/9304908/how-can-i-filter-a-django-query-with-a-list-of-values 참고한 자료