Search code examples
pythondjangodjango-modelsdjango-rest-frameworkattributeerror

'QuerySet' object has no attribute 'completed'


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'

Solution

  • 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