Question

Just started with Django but hit a bit of a wall - I decided to experiment with writing a simple blog engine while referring to the django-basic-apps library.

In blog/urls.py, I have this entry to map to the actual post by date, e.g. blog/2009/aug/01/test-post

urlpatterns = patterns('',
    url(r'^(?P<year>\d{4})/(?P<month>\w{3})/(?P<day>\d{1,2})/(?P<slug>[-\w]+)/$', 'blog.views.post_detail'),
    ...

And the view for rendering the post:

def post_detail(request, slug, year, month, day, **kwargs):
return date_based.object_detail(
    request,
    year = year,
    month = month,
    day = day,
    date_field = 'created_at',
    slug = slug,
    queryset = Content.objects.filter(published=True),
    **kwargs
)

In the model I implemented get_absolute_url so that one the main blog page I could click on a post's title to view it:

class Content(models.Model):
    ...
@permalink
def get_absolute_url(self):
    return ('blog.views.post_detail', (), {
        'slug': self.slug,
        'year': self.created_at.year,
        'month': self.created_at.strftime('%b').lower(),
        'day': self.created_at.day
    })

Finally, in the main page's post list, the permalink is supposed to be inserted in the title:

{% for content in object_list %}
<div class="content_list">
<h3 class="content_title"><a href="{{ content.get_absolute_url }}">{{ content.title }}</a></h3>
<p class="content_date">{{ content.published_at|date:"Y F d"}}</p>
<p class="content_body">{{ content.body }}</p>
<p class="content_footer">updated by {{ content.author }} at {{ content.updated_at|timesince }} ago</p>
</div>
{% endfor %}

However the link shows up as empty, and when I try to call content.get_absolute_url() from the django shell the error gets thrown:

NoReverseMatch: Reverse for '<function post_detail at 0xa3d59cc>' with arguments '()' and keyword arguments '{'year': 2009, 'slug': u'another_test', 'day': 15, 'month': 'aug'}' not found.

Edit: Turns out it was a Python namespace problem (see below). But anyway, was my urls.py as shown above incorrect?

Was it helpful?

Solution

Googled around for other newbie Django tutorials and got the idea of putting all the URLs into the parent folder urls.py, and that seemed to solve the problem. :) So in the end, my main urls.py now has:

from djangoblog.blog import views
urlpatterns = patterns('',

    (r'^blog/(?P<year>\d{4})/(?P<month>\w{3})/(?P<day>\d{1,2})/(?P<slug>[-\w]+)/$',
    views.post_detail),
    (r'^blog/(?P<year>\d{4})/(?P<month>\w{3})/(?P<day>\d{1,2})/$',
    views.post_archive_day),
    ...

Edit: Edit: After 2 days of casual hacking I understand URLconfs + django views a lot better now, fortunately. :) I've moved the patterns back into blog/urls.py, got rid of all the custom date-based views and call them from urls.py instead, and properly named patterns for items that need to be @permalinked.

urls.py with named pattern:

from blog import views
...
(r'(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{1,2})/(?P<slug>[-\w]+)/$',
    'object_detail', dict(info_dict, slug_field='slug', month_format='%m'),
    'post_detail'),
...
(r'category/(?P<slug>[-\w]+)/$', views.category_detail),

models.py:

class Post:
    @permalink
    def get_absolute_url(self):
    return ('post_detail', (), {
                  ....

class Category:
    @permalink
def get_absolute_url(self):
    return ('blog.views.category_detail', (), {'slug': self.slug})
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top