Reputation: 563
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?
Upvotes: 2
Views: 5961
Reputation: 563
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})
Upvotes: 3