class QuizGenerator:
def generate():
quiz_objects_ids = Quiz.objects.values_list("id", flat=True)
id_list = list(quiz_objects_ids)
generate_count = 10
quiz_ids = random.sample(id_list, k=generate_count)
return Quiz.objects.filter(id__in=quiz_ids)
기존에 팀원분께서 만들어주신 코드는
특정 모델에만 적용이 가능하게 되어있다.
이 코드를 다른 모델이 생겼을 때도 사용 가능하게 바꿔보면 어떨까?
# crawled_data/generators.py
from crawled_data.models import NaverQuiz, KrDictQuiz
import random
class QuizGenerator:
def generate(model):
quiz_objects_ids = model.objects.values_list("id", flat=True)
id_list = list(quiz_objects_ids)
generate_count = 10
quiz_ids = random.sample(id_list, k=generate_count)
return model.objects.filter(id__in=quiz_ids)
함수에서 model
이라는 인자를 받아오게 고친 뒤,
기존 모델이 들어가는 부분을 전부 model
로 고쳤다.
그리고, view
에서 호출할 때 모델 값을 담아서 보내주면 될 것 같았다!
1번 안
# crawled_data/serializers.py
...
def generate_quiz_serializer(model):
class GeneratedQuizSerializer(serializers.ModelSerializer):
if model == NaverQuiz:
options = NaverOptionSerializer(many=True)
class Meta:
model = NaverQuiz
fields = "__all__"
elif model == KrDictQuiz:
explain = KrDictExampleSerializer(many=True)
class Meta:
model = KrDictQuiz
fields = "__all__"
return GeneratedQuizSerializer
이왕이면 시리얼라이저도 하나로 바꿔주고 싶어서 함수 하나로 묶어봤는데
분리하는 게 더 나을 것 같기도 하고....
2번 안 (분리)
# crawled_data/serializers.py
...
class NaverQuizSerializer(serializers.ModelSerializer):
options = NaverOptionSerializer(many=True)
class Meta:
model = NaverQuiz
fields = "__all__"
class KrDictQuizSerializer(serializers.ModelSerializer):
explain = KrDictExampleSerializer(many=True)
example = KrDictExampleSerializer(many=True)
class Meta:
model = KrDictQuiz
fields = "__all__"
음!!
아무리 생각해도 2번이 훨씬 나을 것 같다.
무조건 메소드를 통일하는 게 정답은 아닌듯 함...
from rest_framework import status
from rest_framework.decorators import APIView
from rest_framework.response import Response
from crawled_data.models import NaverQuiz, KrDictQuiz
from crawled_data.generators import QuizGenerator
from crawled_data.serializers import NaverQuizSerializer, KrDictQuizSerializer
class NaverQuizView(APIView):
def get(self, request):
quiz = QuizGenerator.generate(NaverQuiz)
serializer = NaverQuizSerializer(quiz, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
class KrDictQuizView(APIView):
def get(self, request):
quiz = QuizGenerator.generate(KrDictQuiz)
serializer = KrDictQuizSerializer(quiz, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
각 모델에 따라서 퀴즈를 불러와서 보내는 generator를 작성했다.
이건 메소드를 합칠 수 있을 것 같은데...
작동 잘 되는지 확인해보고 디벨롭 해봐야겠다.
from django.urls import path
from crawled_data import views
urlpatterns = [
path("naver/", views.NaverQuizView.as_view(), name="naver_quiz_view"),
path("krdict/", views.KrDictQuizView.as_view(), name="krdict_quiz_view"),
]
역시나! 한번에 될 리가 없음.
문제가 뭐였나 보니 함수 호출 시 안에 넣어주는 값 문제였다.
# crawled_data/views.py
...
class NaverQuizView(APIView):
def get(self, request):
quiz = QuizGenerator.generate(NaverQuiz)
serializer = NaverQuizSerializer(quiz, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
...
generate
함수를 호출 할 때 NaverQuiz
를 넣어주면 될 줄 알았다?
근데 안됨...ㅋ
형태가 다르게 넘어간다.
이렇게 class
객체로 넘어가서 실제로 generate
함수에서는 아래처럼 들어가는거다.
# crawled_data/generators.py
...
class QuizGenerator:
def generate(model):
quiz_objects_ids = <class 'crawled_data.models.NaverQuiz'>.objects.values_list("id", flat=True)
id_list = list(quiz_objects_ids)
이러면 되겠냐고!!! 당연히 못찾지...
그래서 형태 자체는 문자열로 넘겨줘서 generate
함수 안에서 model
을 찾아오는 식으로 바꿔야 할 것 같다.
# crawled_data/generators.py
...
my_model = {"n": NaverQuiz, "k": KrDictQuiz}
class QuizGenerator:
def generate(key):
quiz_objects_ids = my_model[key].objects.values_list("id", flat=True)
id_list = list(quiz_objects_ids)
generate_count = min(10, len(id_list))
quiz_ids = random.sample(id_list, k=generate_count)
return my_model[key].objects.filter(id__in=quiz_ids)
딕셔너리로 해서 들고오면 안되나? 라는 생각이 들었다.
근데 이것도 안되더라...
하...................................................................................................................
나는 바보다...
DB에 loaddata
안한거 까먹고 아니 왜 안불러와져!! 이러고 있었는데
당연히 안되지 이자식아...............................................................
ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
그니까 사실 첫번째에 짰던 generator
코드 자체가 문제는 아니었던거다..................................................................
이거 기반으로 다시 고쳐야겠다.
진짜로 데이터 있는 DB를 들고와서 실험해봤다.
AttributeError: Got AttributeError when attempting to get a value for field `explain` on serializer `KrDictQuizSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `KrDictQuiz` instance.
Original exception text was: 'KrDictQuiz' object has no attribute 'explain'.
오류가 뜬다.
그래도 아까같은 오류가 아니라 해결의 기미가 보인다 !!!
아... 이것도 너무 어이없음
진짜 휴먼에러임
# crawled_data/serializers.py
...
class KrDictQuizSerializer(serializers.ModelSerializer):
explains = KrDictExplainSerializer(many=True)
examples = KrDictExampleSerializer(many=True)
...
KrDictExplainSerializer
으로 써야되는데 저걸 Example
로 써놨더라..
글고 related_name
이 explains
인데 explain
하고 써놔서 안됐던거임
휴먼에러 레전드다 진짜...
이제 걍 화나지도 않고 웃김
하..
됐다............
ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ
진짜 감사합니다 하느님부처님알라신님어쩌고무튼종교의신님그리고코딩의신님...