Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python

Christopher Gunawan
Christopher Gunawan
10,754 Points

Receiving error when trying to edit question

Receiving this error when trying to edit question:

RelatedObjectDoesNotExist at /courses/1/edit_question/1

Question has no multiplechoicequestion.

@login_required
def edit_question(request, quiz_pk, question_pk):
    question = get_object_or_404(models.Question, pk=question_pk, quiz_id=quiz_pk)
    if hasattr(question, 'truefalsequestion'):
        form_class = forms.TrueFalseQuestionForm
        question = question.truefalsequestion
    else:
        form_class = forms.MultipleChoiceQuestionForm
        question = question.multiplechoicequestion

    form = form_class(instance=question)

    if request.method == 'POST':
        form = form_class(request.POST, instance=question)
        if form.is_valid():
            form.save()
            messages.success(request, "Updated question")
            return HttpResponseRedirect(question.quiz.get_absolute_url())
    return render(request, 'courses/question_form.html', {'form': form,
                                                         'quiz': question.quiz})

What am I doing wrong?

Christopher Gunawan
Christopher Gunawan
10,754 Points

I have followed along with Kenneth and I'm not sure why my code does not work.

Christopher Gunawan
Christopher Gunawan
10,754 Points

This line works:

        form_class = forms.TrueFalseQuestionForm
        question = question.truefalsequestion

But multiplechoicequestion does not. Strange...

3 Answers

Hi there, I have downloaded the final version of the code from the video resource and the issue is that there is only 1 question with an ID of 2 in the database where the query is asking for a question with an ID of 4. To be honest I am unsure if this project has been fully completed.

You can test this out in the shell by doing the following

>>> from courses.models import Question
>>> question = Question.objects.get(pk=4) # this is the question_pk passed in via the URL (request)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/Users/stuartmcintosh/Code/Python/treehouse_projects/social_team_builder/venv/lib/python3.6/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/Users/stuartmcintosh/Code/Python/treehouse_projects/social_team_builder/venv/lib/python3.6/site-packages/django/db/models/query.py", line 379, in get
    self.model._meta.object_name
courses.models.DoesNotExist: Question matching query does not exist.
>>> question = Question.objects.all()
>>> question
<QuerySet [<Question: What all characters can be in a string?>]>
>>> question.count()
1
>>> question[0].id
2
>>>

Hi there this a related filed issue. The model Question has a no related TrueFalseQuestion with the Question that you are looking at 1.

Christopher Gunawan
Christopher Gunawan
10,754 Points

But TrueFalseQuestion inherits from Question, so there is a relation. Is there something else I am missing?

Christopher Gunawan
Christopher Gunawan
10,754 Points

From models.py

class MultipleChoiceQuestion(Question):
    shuffle_answers = models.BooleanField(default=False)


class TrueOrFalseQuestion(Question):
    pass

Hi there, can you point me to the code and I will have a look...

Christopher Gunawan
Christopher Gunawan
10,754 Points

from models.py

class Question(models.Model):
    quiz = models.ForeignKey(Quiz, on_delete=models.CASCADE)
    order = models.IntegerField(default=0)
    prompt = models.TextField()

    class Meta:
        ordering = ['order', ]

    def get_absolute_url(self):
        return self.quiz.get_absolute_url()

    def __str__(self):
        return self.prompt


class MultipleChoiceQuestion(Question):
    shuffle_answers = models.BooleanField(default=False)


class TrueOrFalseQuestion(Question):
    pass
Christopher Gunawan
Christopher Gunawan
10,754 Points

from views.py

@login_required
def edit_question(request, quiz_pk, question_pk):
    question = get_object_or_404(models.Question, pk=question_pk, quiz_id=quiz_pk)
    if hasattr(question, 'truefalsequestion'):
        form_class = forms.TrueFalseQuestionForm
        question = question.truefalsequestion
    else:
        form_class = forms.MultipleChoiceQuestionForm
        # TODO Fix this
        question = question.multiplechoicequestion

    form = form_class(instance=question)
    answer_forms = forms.AnswerInlineFormSet(
        queryset=form.instance.answer_set.all()
        )

    if request.method == 'POST':
        form = form_class(request.POST, instance=question)
        answer_forms = forms.AnswerInlineFormSet(
            request.POST, queryset=form.instance.answer_set.all()
            )
        if form.is_valid() and answer_forms.is_valid():
            form.save()
            answers = answer_forms.save(commit=False)
            for answer in answers:
                answer.question = question
                answer.save()
            for answer in answer_forms.deleted_objects:
                answer.delete()
            messages.success(request, "Updated question")
            return HttpResponseRedirect(question.quiz.get_absolute_url())
    return render(request, 'courses/question_form.html', {'form': form, 'quiz': question.quiz, 'formset': answer_forms})
Christopher Gunawan
Christopher Gunawan
10,754 Points

from question_form.html

{% extends "courses/layout.html" %}
{% load course_extras %}

{% block title %}{{ form.instance.prompt|default:"New question" }} | {{ quiz.course.title }}
{{ block.super }} {% endblock %}

{% block breadcrumbs %}
    <li><a href="{% url 'courses:detail' pk=quiz.course.pk %}">{{ quiz.course.title }}</a></li>
    <li><a href="{% url 'courses:quiz' course_pk=quiz.course.pk step_pk=quiz.pk %}">{{ quiz.title }}
    </a></li>
{% endblock %}

{% block content %}
    <div class="row columns">
        {{ block.super }}
        <h1>{{ form.instance.prompt|default:"Make a new question" }}</h1>
        <form method="POST" action="">
            {% csrf_token %}
            {{ form.as_p }}

            {{ formset.management_form }}

            <table role="grid" class="stack hover" style="width:100%">
                <thead>
                <tr>
                    <th scope="col" class="text-center" style="width: 10%">Order</th>
                    <th scope="col" class="text-center">Text</th>
                    <th scope="col" class="text-center" style="width: 10%">Correct</th>
                    <th scope="col" class="text-center" style="width: 10%">Delete?</th>
                </tr>
                </thead>
                <tbody class="order">
                    {% for form in formset %}
                        <tr class="answer-form {% if form.instance.pk %}item{% else %}new{% endif %}">
                            <td>{{ form.id }} {{ form.order }}</td>
                            <td>{{ form.text }}</td>
                            <td class="text-center">{{ form.correct }}</td>
                        {% if form.instance.pk %}
                            <td class="text-center">{{ form.DELETE }}</td>
                        {% else %}
                            <td class="text-center"></td>
                        {% endif %}
                        </tr>
                    {% endfor %}
                </tbody>
            </table>
            <input type="submit" class="button" value="Save">
        </form>
    </div>
{% endblock %}

{% block css %}
    {{ form.media.css }}
{% endblock %}

{% block javascript %}
    {% load static from staticfiles %}
    {{ form.media.js }}
    <script src="{% static 'js/vendor/jquery.formset.js' %}"></script><script>
        $('.answer-form').formset({addText: 'add answer', deleteText: 'remove'});
    </script>
{% endblock %}
Christopher Gunawan
Christopher Gunawan
10,754 Points

The error response:

RelatedObjectDoesNotExist at /courses/1/edit_question/4

Question has no multiplechoicequestion.

Request Method:     GET
Request URL:    http://127.0.0.1:8000/courses/1/edit_question/4
Django Version:     2.1.1
Exception Type:     RelatedObjectDoesNotExist
Exception Value:    

Question has no multiplechoicequestion.

Exception Location:     C:\Users\user\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\models\fields\related_descriptors.py in __get__, line 414
Python Executable:  C:\Users\user\AppData\Local\Programs\Python\Python37\python.exe
Python Version:     3.7.0
Python Path:    

['C:\\Users\\user\\learning_site',
 'C:\\Users\\user\\learning_site',
 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python37\\python37.zip',
 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python37\\DLLs',
 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python37\\lib',
 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python37',
 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python37\\lib\\site-packages',
 'C:\\Program Files\\JetBrains\\PyCharm '
 '2018.2.3\\helpers\\pycharm_matplotlib_backend']

Server time:    Tue, 11 Sep 2018 11:41:19 +0700