user10089943
user10089943

Reputation:

Django 2.1 NoReverseMatch error Using post method in Class Based Views

Url :

re_path(r'^detail/(?P<slug>\w+)/$', ProblemDetail.as_view(), name='problem_detail'),

View :

class ProblemDetail(View):
    template_name='problem/problem_detail.html'
    form_class=AnswerForm

    def get(self,request,slug):
        context={'problem':Problem.objects.get(slug=slug),'form':self.form_class()}
        return render(request,self.template_name,context)

    def post(self,request,slug):
        bound_form=self.form_class(request.POST)
        obj=Problem.objects.get(slug=slug)
        real_answer=obj.answer
        if bound_form.is_valid():
            if bound_form.cleaned_data['answer'] == real_answer:
                return render(request,
                              'problem/Answerstatus.html', 
                              {'message':'Good Job !'})
        else:
            return render(request,
                          'problem/Answerstatus.html',
                          {'message':'Wrong ! Try Again  !'})

Template :

{% extends "problem/base_problem.html" %}

{% block content%}
<h2>{{problem.p_name}}</h2>
<h3>{{problem.difficulty}}</h3>
<p>{{problem.p_description}}</p>
<form  action= "{% url 'problem_detail' %}" method="post">
  {% csrf_token %}
  {{ form.as_p }}
  <button type="submit" > Check </button>
</form>
{% endblock %}

The above template is a rough idea for testing (Its not Final template,needs tons of changes, we know that.)

I get the following error :

Reverse for 'problem_detail' with no arguments not found. 1 pattern(s) tried: ['detail/(?P<slug>\\w+)/$']

Upvotes: 1

Views: 303

Answers (3)

AbrarWali
AbrarWali

Reputation: 647

Add get_absolute_url method to your model like this :

    def get_absolute_url(self):
        return reverse('problem_detail',kwargs={'slug':self.slug})

Also in your templates :

{% block body-block %}
<h2>{{problem.p_name}}</h2>
<h5>{{problem.difficulty}}</h5>
<p>{{problem.p_description}}</p>
<form  action= "{{ problem.get_absolute_url }}" method="post"> # Pay Attention here
  {% csrf_token %}
  {{ form.as_p }}
  <button type="submit" > Check </button>
</form>
{% endblock %}

This will fetch the url and the regex will match .

Upvotes: 0

Alasdair
Alasdair

Reputation: 308909

It looks as if the problem is occuring in a {% url %} tag in your problem/Answerstatus.html, but we can't be sure because you haven't included that template in your question.

It looks as if you need to include the problem in your template whenever you render the template, for example,

return render(request, 'problem/Answerstatus.html', {'problem': obj, 'message':'Good Job !'})

and then in the template, include the slug in the {% url %} tag:

{% url 'problem_detail' problem.slug %}

Upvotes: 1

Uroš Trstenjak
Uroš Trstenjak

Reputation: 903

You should add slug argument when you are returning in post method. Try returning HttpResponseRedirect and reverse to your url together with slug in args list.

return HttpResponseRedirect(reverse('problem_detail', args=[slug]))

Upvotes: 1

Related Questions