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 Django Forms Inlines and Media Inline Model Formset

nuri jeon
nuri jeon
14,376 Points

Inline Model Formset! NoReverseMatch at /courses/1/create_question/mc/

Hello :) So I was following "Inline Model Formset" course and I tried to create a question on quiz_detail.html but it says

NoReverseMatch at /courses/1/create_question/mc/ Reverse for 'create_answer' with keyword arguments '{'question_pk': None}' not found. 1 pattern(s) tried: ['courses/(?P<question_pk>\d+)/create_answer/$']

This error and I don't know why this is happening @@; I have no problem what Kenneth did(editing question) but creating question doesn't work! Please help me X( Thanks.

2 Answers

Henrik Christensen
seal-mask
.a{fill-rule:evenodd;}techdegree
Henrik Christensen
Python Web Development Techdegree Student 38,322 Points

Any chance you could format the text? It's really hard to read when it's written like normal text :-/

To format the text you add 3x backticks (`) followed by the language to format for and when done formatting you end it with 3x backticks again.

Click the Markdown Cheatsheet link below the textarea field for information on how to do it or check out this video at 1:55

nuri jeon
nuri jeon
14,376 Points

Ok :D I fixed it! I think my qutation mark didn't do what I exepcted but yah! So first code is views.py and 2nd is forms.py and 3rd is question_form.html and last one is answer_form.html Thank you! hope I put down everything to solve this problem @.@

from itertools import chain

from django.contrib import messages
from django.contrib.auth.decorators import login_required

from django.http import HttpResponseRedirect
from django.shortcuts import render, get_object_or_404

from . import models
from . import forms

# Create your views here.
def course_list(request):
    courses = models.Course.objects.all()
    email='questions@learning_site.com'
    return render(request, 'courses/course_list.html',{'courses':courses, 'email':email})


def course_detail(request, pk):
    course = get_object_or_404(models.Course, pk=pk)
    steps = sorted(chain(course.text_set.all(), course.quiz_set.all()), key=lambda step:step.order)
    return render(request, 'courses/course_detail.html', {'course':course, 'steps':steps})


def text_detail(request, course_pk, step_pk):
    step = get_object_or_404(models.Text, course_id=course_pk, pk=step_pk) #course_id is a foreign field    
    return render(request, 'courses/text_detail.html', {'step':step})


def quiz_detail(request, course_pk, step_pk):
    step = get_object_or_404(models.Quiz, course_id=course_pk, pk=step_pk) #course_id is a foreign field    
    return render(request, 'courses/quiz_detail.html', {'step':step})   

@login_required
def create_quiz(request, course_pk):
    course = get_object_or_404(models.Course, pk=course_pk)
    form = forms.QuizForm()

    if request.method == 'POST':
        form = forms.QuizForm(request.POST)
        if form.is_valid():
            quiz = form.save(commit=False)  
            quiz.course = course
            quiz.save()
            messages.add_message(request, messages.SUCCESS, "Quiz added!")
            return HttpResponseRedirect(quiz.get_absolute_url())
    return render(request, 'courses/quiz_form.html', {'form':form, 'course':course})

@login_required
def edit_quiz(request, course_pk, quiz_pk):
    quiz = get_object_or_404(models.Quiz, pk=quiz_pk, course_id=course_pk)
    form = forms.QuizForm(instance = quiz)
    if request.method =='POST':
        form = forms.QuizForm(instance=quiz, data=request.POST)
        if form.is_valid():
            quiz = form.save()
            messages.success(request, "Updated {}".format(form.cleaned_data['title']))
            return HttpResponseRedirect(quiz.get_absolute_url())
    return render(request, 'courses/quiz_form.html', {'course':quiz.course, 'form':form})       

@login_required
def create_question(request, quiz_pk, question_type):
    quiz = get_object_or_404(models.Quiz, pk=quiz_pk)
    if question_type == 'tf':
        form_class = forms.TrueFalseQuestionForm
    else:
        form_class = forms.MultipleChoiceQuestionForm
    form = form_class()
    answer_forms=forms.AnswerInlineFormSet(
        queryset=models.Answer.objects.none()
    )
    if request.method == 'POST':
        form = form_class(request.POST)
        answer_forms = forms.AnswerInlineFormSet(
            request.POST,
            queryset = models.Answer.objects.none()
        )
        if form.is_valid() and answer_forms.is_valid():
            question = form.save(commit=False)
            question.quiz = quiz
            question.save()
            answers=answer_forms.save(commit=False)
            for answer in answers:
                answer.question=question
                answer.save()
            messages.success(request, "Added question")
            return HttpResponseRedirect(quiz.get_absolute_url())
    return render(request, 'courses/question_form.html', {'form':form, 'quiz':quiz, 'formset':answer_forms })   


@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)
    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()
            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})           

@login_required
def answer_form(request, question_pk, answer_pk=None):
    question = get_object_or_404(models.Question, pk=question_pk)
    formset = forms.AnswerFormSet(queryset=question.answer_set.all())

    if request.method == 'POST':
        formset = forms.AnswerFormSet(request.POST,
                                      queryset=question.answer_set.all())

        if formset.is_valid():
            answers = formset.save(commit=False)

            for answer in answers:
                answer.question = question
                answer.save()
            messages.success(request, "Added answers")
            return HttpResponseRedirect(question.quiz.get_absolute_url())
    return render(request, 'courses/answer_form.html', {
            'formset': formset,
            'question': question
    })
from django import forms

from . import models

class QuizForm(forms.ModelForm):
    class Meta:
        model = models.Quiz
        fields = [
            'title',
            'description',
            'order',
            'total_questions'
        ]

class TrueFalseQuestionForm(forms.ModelForm):
    class Meta:
        model = models.TrueFalseQuestion
        fields = [
            'order',
            'prompt'
        ]       

class MultipleChoiceQuestionForm(forms.ModelForm):
    class Meta:
        model = models.MultipleChoiceQuestion
        fields = ['order', 'prompt', 'shuffle_answers']     

class AnswerForm(forms.ModelForm):
    class Meta:
        model = models.Answer
        fields = [
            'order',
            'text',
            'correct'
        ]       

AnswerFormSet=forms.modelformset_factory(
    models.Answer,
    form=AnswerForm,

)       


AnswerInlineFormSet = forms.inlineformset_factory(
    models.Question,
    models.Answer,
    extra = 2,
    fields = ('order', 'text', 'correct'),
    formset=AnswerFormSet,
    min_num=1,

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

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

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

{% block content %}
    <div class="row columns">
        <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>
        {% if user.is_authenticated %}
            <hr>
            <a href="{% url 'create_answer' question_pk=form.instance.pk %}" class="button">Add Answer</a>
        {% endif %}
    </div>
{% endblock %}
{% extends "courses/layout.html" %}
{% load course_extras %}

{% block title %}{{ question.prompt }}New Answer | {{ question.prompt }}{% endblock %}

{% block breadcrumbs %}
    <li><a href="{% url 'course_detail' course_pk=question.quiz.course.pk %}">{{ question.quiz.course.title }}</a></li>
    <li><a href="{% url 'quiz' course_pk=question.quiz.course.pk quiz_pk=question.quiz.pk %}">{{ question.quiz.title }}</a></li>
    <li>{{ question.prompt }}</li>

{% endblock %}


{% block content %}
    <div class="row columns">
        <h1>make a new answer</h1>
        <form method="POST" action="">
            {% csrf_token %}
            <section>
                {{formset}}
            </section>
            <input type="submit" class="button" value="save">
    </div>
{% endblock %}
Henrik Christensen
seal-mask
.a{fill-rule:evenodd;}techdegree
Henrik Christensen
Python Web Development Techdegree Student 38,322 Points

Looks like the problem might be in your template - your urls are not set correctly..

In the videos it's like this:

<a href="{% url 'courses:create_answer' question_pk=form.instance.pk %}" class="button">Add Answer</a>

But in your template you have done it like this:

<a href="{% url 'create_answer' question_pk=form.instance.pk %}" class="button">Add Answer</a>

And it looks like all your urls are missing that courses: part