简体   繁体   中英

Django “reverse for ____ with arguments”… error

I'm receiving the following error

Error: Reverse for placeinterest with arguments ('',) and keyword arguments {} not found. 1 pattern(s) tried:

[u'polls/(?P<section_id>[0-9]+)/placeinterest/$']

I worked through the Django example for a polling app, and now I'm trying to create a class registration app adapting what I already have. Error points to line 5 here:

<h1>{{ section.class_name }}</h1>

{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}

<form action="{% url 'polls:placeinterest' section.id %}" method="post">
{% csrf_token %}
<input type="radio" name="incr" id="incr" value="incr" />
<label for="incr"></label><br />
<input type="submit" value="Placeinterest" />
</form>

But I think the problem is in my placeinterest function:

def placeinterest(request, section_id):
    section = get_object_or_404(Section, pk=section_id)
    try:
        selected_choice = section.num_interested
    except (KeyError, Section.num_interested.DoesNotExist):
        # Redisplay the question voting form.
        return render(request, 'polls/detail.html', {
            'section': section,
            'error_message': "You didn't select a choice.",
        })
    else:
        section.num_interested += 1
        section.save()
        # Always return an HttpResponseRedirect after successfully dealing
        # with POST data. This prevents data from being posted twice if a
        # user hits the Back button.
        return HttpResponseRedirect(reverse('polls:results', args=(section.id,)))

I'm not sure what my POST call should be if my Section class looks like this:

class Section(models.Model):
    class_name = models.CharField(max_length=200)
    num_interested = models.IntegerField(default=0)
    pub_date = models.DateTimeField('date published')
    def __str__(self):
        return self.class_name
    def was_published_recently(self):
        return self.pub_date >= timezone.now() - datetime.timedelta(minutes=3)
    def some_interested(self):
        if self.num_interested > 0:
            return "There is currently interest in this class"
        else:
            return "There is currently no interest in this class"

The results part comes up fine in my browser, and here is urls.py for good measure:

from django.conf.urls import url

from . import views

app_name = 'polls'
urlpatterns = [
    url(r'^$', views.IndexView.as_view(), name='index'),
    url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='detail'),
    url(r'^(?P<pk>[0-9]+)/results/$', views.ResultsView.as_view(), name='results'),
    url(r'^(?P<section_id>[0-9]+)/placeinterest/$', views.placeinterest, name='placeinterest'),
]

Edit: adding the original code from the example in hopes that might help someone see where I went wrong:

urls:

from django.conf.urls import url

from . import views

app_name = 'polls'
urlpatterns = [
    url(r'^$', views.IndexView.as_view(), name='index'),
    url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='detail'),
    url(r'^(?P<pk>[0-9]+)/results/$', views.ResultsView.as_view(), name='results'),
    url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
]

vote function in views.py:

def vote(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    try:
        selected_choice = question.choice_set.get(pk=request.POST['choice'])
    except (KeyError, Choice.DoesNotExist):
        # Redisplay the question voting form.
        return render(request, 'polls/detail.html', {
            'question': question,
            'error_message': "You didn't select a choice.",
        })
    else:
        selected_choice.votes += 1
        selected_choice.save()
        # Always return an HttpResponseRedirect after successfully dealing
        # with POST data. This prevents data from being posted twice if a
        # user hits the Back button.
        return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))

detail.html, where I'm having problems after making my changes:

<h1>{{ question.question_text }}</h1>

{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}

<form action="{% url 'polls:vote' question.id %}" method="post">
{% csrf_token %}
{% for choice in question.choice_set.all %}
    <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
    <label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br />
{% endfor %}
<input type="submit" value="Vote" />
</form>

The error has nothing to do with your view. It specifically says it's trying to match the URL named placeinterest in the error. It knows the URL exists, but the arguments are wrong.

It thinks you're trying to pass an empty string as a positional argument. This means that section.id is probably None when the template is rendered. It's converting the null value into an empty string and passing it as a positional argument, hence ('',) . That's a tuple with one empty string value in it.

The problem is here:

<form action="{% url 'polls:placeinterest' section.id %}" method="post">

Django can't figure out the url argument as it's misconfigured. Use this:

<form action="{% url 'polls:placeinterest' section_id=section.id %}" method="post">

You also need to ensure that section id is valid a number (be careful of what you supply as "section" as your context.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM