In my quiz app, every user can have multiple attempts. My model setup is as follows:
class Quiz(models.Model):
title = models.CharField(max_length=15)
slug = models.SlugField(blank=True)
questions_count = models.IntegerField(default=0)
class Question(models.Model):
quiz = models.ForeignKey(Quiz, on_delete=models.CASCADE)
label = models.CharField(max_length=1000)
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
answer = models.CharField(max_length=100)
is_correct = models.BooleanField('Correct answer', default=False)
class QuizTaker(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
quiz = models.ForeignKey(Quiz, on_delete=models.CASCADE)
correct_answers = models.IntegerField(default=0)
completed = models.BooleanField(default=False)
attempt_number = models.PositiveIntegerField(default=0)
I get the error in my serializer when I try to determine if a given quiz has been completed:
class MyQuizListSerializer(serializers.ModelSerializer):
questions_count = serializers.SerializerMethodField()
completed = serializers.SerializerMethodField()
progress = serializers.SerializerMethodField()
score = serializers.SerializerMethodField()
class Meta:
model = Quiz
fields = ['id', 'title', 'type_of_content', 'song', 'slug',
'questions_count', 'completed', 'score', 'progress']
read_only_fields = ['questions_count', 'completed', 'progress']
def get_completed(self, obj):
try:
quiztaker = QuizTaker.objects.filter(user=self.context['request'].user, quiz=obj)
for attempt in quiztaker:
return quiztaker.completed #the error comes from this line
except QuizTaker.DoesNotExist:
return None
Can anybody tell me why I am getting this error? I am filtering because the user can have multiple attempts, therefore I get a queryset, and therefore I must loop through it. The QuizTaker
model does have a completed
field, so what is the issue?
Here is the full traceback:
Traceback (most recent call last):
File "C:\Users\mvren\miniconda3\envs\myRuEnv\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Users\mvren\miniconda3\envs\myRuEnv\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\mvren\miniconda3\envs\myRuEnv\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\mvren\miniconda3\envs\myRuEnv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "C:\Users\mvren\miniconda3\envs\myRuEnv\lib\site-packages\django\views\generic\base.py", line 71, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\mvren\miniconda3\envs\myRuEnv\lib\site-packages\rest_framework\views.py", line 505, in dispatch
response = self.handle_exception(exc)
File "C:\Users\mvren\miniconda3\envs\myRuEnv\lib\site-packages\rest_framework\views.py", line 465, in handle_exception
self.raise_uncaught_exception(exc)
File "C:\Users\mvren\miniconda3\envs\myRuEnv\lib\site-packages\rest_framework\views.py", line 476, in raise_uncaught_exception
raise exc
File "C:\Users\mvren\miniconda3\envs\myRuEnv\lib\site-packages\rest_framework\views.py", line 502, in dispatch
response = handler(request, *args, **kwargs)
File "C:\Users\mvren\miniconda3\envs\myRuEnv\lib\site-packages\rest_framework\generics.py", line 199, in get
return self.list(request, *args, **kwargs)
File "C:\Users\mvren\miniconda3\envs\myRuEnv\lib\site-packages\rest_framework\mixins.py", line 46, in list
return Response(serializer.data)
File "C:\Users\mvren\miniconda3\envs\myRuEnv\lib\site-packages\rest_framework\serializers.py", line 760, in data
ret = super().data
File "C:\Users\mvren\miniconda3\envs\myRuEnv\lib\site-packages\rest_framework\serializers.py", line 260, in data
self._data = self.to_representation(self.instance)
File "C:\Users\mvren\miniconda3\envs\myRuEnv\lib\site-packages\rest_framework\serializers.py", line 677, in to_representation
return [
File "C:\Users\mvren\miniconda3\envs\myRuEnv\lib\site-packages\rest_framework\serializers.py", line 678, in <listcomp>
self.child.to_representation(item) for item in iterable
File "C:\Users\mvren\miniconda3\envs\myRuEnv\lib\site-packages\rest_framework\serializers.py", line 529, in to_representation
ret[field.field_name] = field.to_representation(attribute)
File "C:\Users\mvren\miniconda3\envs\myRuEnv\lib\site-packages\rest_framework\fields.py", line 1905, in to_representation
return method(value)
File "C:\Users\mvren\OneDrive\Documents\Coding\Russki\mysite\quizzes\serializers.py", line 48, in get_completed
return quiztaker.completed
Exception Type: AttributeError at /quizzes/api/my-quizzes/Melissavr
Exception Value: 'QuerySet' object has no attribute 'completed'
Simple mistake, the quiztaker
object is a QuerySet
.
You should be using the attempt
variable assigned in the for
loop:
for attempt in quiztaker:
return attempt.completed #the error comes from this line