lorless
lorless

Reputation: 4488

Django dispatch() got an unexpected keyword argument in Django

I have overwritten the dispatch methods on my view classes so they require the user to be logged in.

Example:

class IndexView(generic.ListView):
    template_name='quotes/index.html'
    context_object_name = 'book_list'

    @method_decorator(login_required)
    def dispatch(self, args):
        return super(IndexView, self).dispatch(args)
    def get_queryset(self):
        """Return all the book objects"""
        return Book.objects.all()

class DetailView(generic.DetailView):
   model = Book
   template_name = 'quotes/detail.html'

   @method_decorator(login_required)
   def dispatch(self, request, args, kwargs):
        return super(DetailView, self).dispatch(request, args, kwargs)
   def get_queryset(self):
       """
       Excludes any polls that aren't yet published
       """
       return Book.objects.all()

This works nicely until I use a URL pattern like this:

     url(r'^book/(?P<pk>\d+)/$', views.DetailView.as_view(), name='detail'),

Then it gives me the error

    dispatch() got an unexpected keyword argument 'pk'

DetailView needs that argument for the query_set function yet the dispatch is catching it and complaining about it. This has happened to me before. I removed all the login functionality and had to start again. I replaced it all and it worked fine even with the pk arg. Now its doing it again and I can't find any reason online. Can anyone help. Will post whatever else you think is necessary.

I know you can add login_required to the URL patterns. Am I just going about this the wrong way? The Django documentation suggests the very method that I am using.

quotes/index.html

    {% extends "base.html" %}

{% block content %}
{% load staticfiles %}

<h2> Books </h2>
{% if book_list %}
    <ul>
    {% for book in book_list %}     
        <li><a href="{% url 'quotes:detail' book.id %}">{{ book.title }}</a></li>
    {% endfor %}
    </ul>
{% else %}
    <p>No books are available.<p>
{% endif %}
<a href="{% url 'quotes:newQuote' %}"><button class="btn btn-primary">Create a New Quote</button></a>
<a href="{% url 'quotes:newBook' %}"><button class="btn btn-primary">Create a New Book</button></a>


{% endblock %}

quotes/urls.py

    from django.conf.urls import patterns, url
from django.contrib.auth.decorators import login_required

from quotes import views

urlpatterns = patterns('',
    #no extra route sp (quotes/)
    url(r'^$', views.IndexView.as_view(), name='index'),
    #looks for id value next to /quotes/ and activates the detail view
    #this regex capture the id value in <pk> probably lt and mt characters define this
    #all these are 'quotes/andthensomething/'
    url(r'^book/(?P<pk>\d+)/$', views.DetailView.as_view(), name='detail'),
    url(r'^quote/(?P<pk>\d+)/$', views.QuoteDetailView.as_view(), name='quoteDetail'),
    url(r'^quote/(?P<quoteID>\d+)/edit/$', views.QuoteEditView2 , name='editQuote'),
    url(r'^quotes/', views.ListQuotesView.as_view(), name='listQuotes'),
    url(r'^newQuote/', views.newQuote, name='newQuote'),
    url(r'^newBook/', views.newBook, name='newBook'),
    url(r'^createQuote/', views.createQuote, name='createQuote'),
    url(r'^createBook/', views.createBook, name='createBook'),
    url(r'^book/(?P<bookID>\d+)/delete/$', views.deleteBook, name='deleteBook'),
    url(r'^quote/(?P<quoteID>\d+)/delete/$', views.deleteQuote, name='deleteQuote'),
    url(r'^book/(?P<pk>\d+)/edit/$', views.BookEditView.as_view(), name='editBook'),
    url(r'^quote/(?P<quoteID>\d+)/update/$', views.updateQuote, name='updateQuote'),
    url(r'^book/(?P<bookID>\d+)/update/$', views.updateBook, name='updateBook'),
    url(r'^logout/', views.logout_view, name="logout"),
    #url(r'^accounts/login/', views.loginProper, name='loginProper'),
)

Upvotes: 2

Views: 2575

Answers (1)

petkostas
petkostas

Reputation: 7460

The correct method call for the dispatch is:

def dispatch(self, request, *args, **kwargs):

So you should:

def dispatch(self, request, *args, **kwargs):
    return super(IndexView, self).dispatch(request, *args, **kwargs)

Upvotes: 5

Related Questions