jazzblue
jazzblue

Reputation: 2437

Django Class Based View CreateView url resolution

I am fairly new to CBV and am trying to make sense of it. I copied the following example from the django doc page:

https://docs.djangoproject.com/en/dev/topics/class-based-views/generic-editing/

models.py

from django.core.urlresolvers import reverse
from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=200)

    def get_absolute_url(self):
        return reverse('author-detail', kwargs={'pk': self.pk})

views.py

from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.core.urlresolvers import reverse_lazy
from myapp.models import Author

class AuthorCreate(CreateView):
    model = Author
    fields = ['name']

class AuthorUpdate(UpdateView):
    model = Author
    fields = ['name']

class AuthorDelete(DeleteView):
    model = Author
    success_url = reverse_lazy('author-list')

urls.py

from django.conf.urls import patterns, url
from myapp.views import AuthorCreate, AuthorUpdate, AuthorDelete

urlpatterns = patterns('',
    # ...
    url(r'author/add/$', AuthorCreate.as_view(), name='author_add'),
    url(r'author/(?P<pk>\d+)/$', AuthorUpdate.as_view(), name='author_update'),
    url(r'author/(?P<pk>\d+)/delete/$', AuthorDelete.as_view(), name='author_delete'),
)

At author/add/ I indeed get the form, but when I enter the string I get the following error:

Reverse for 'author-detail' with arguments '()' and keyword arguments '{'pk': 3}' not found.

It seems like the new entry has been added to the database, but it could not resolve the URL for the next view?

So I am puzzled, what is this get_absolute_url() object's method supposed to do, how does it work (I could not grasp it from the django doc) and how do I fix the issue? Thanks.

EDIT 1: added the template:

author_form.html:

<form action="" method="post">{% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Create" />
</form>

Upvotes: 2

Views: 5930

Answers (1)

czarchaic
czarchaic

Reputation: 6318

By default, when a new model is created django will redirect you to a models absolute url as returned by the get_absolute_url method. In your example you would need to add a url with the name author-detail that accepts a pk keyword argument.

urlpatterns = patterns('',
  # ...
  url(r'author/(?P<pk>\d+)/$', AuthorDetail.as_view(), name='author-detail'),
)

Note the name of the url matches the name of the view in the get_absolute_url method.

Use it in your templates:

{% for author in authors %}
  <a href="{{author.get_absolute_url}}">{{author.name}}</a>
{% endfor %}

Upvotes: 4

Related Questions