I blog in ReSt Part 2

Sat 10 November 2007 by Thejaswi Puthraya

I blog in ReSt Part 2

Once done with setting up the project, we need to code our views and templates to complete the blog. This part deals with coding the views for the blog. The different views that we require are

  • For displaying the landing page
  • For displaying the blog filtered by year
  • For displaying the blog filtered by month
  • For displaying the blog filtered by day
  • Tags to categorize the blog. For this I make use of Django-Tagging

So let's edit the urls.py file in the project directory to reflect on the urlpatterns.

('^blog/$', get_blog_first_page),
('^blog/(?P<year>\d{4})/$', get_posts_by_year),
('^blog/(?P<year>\d{4})/page/(?P<page>\d)/$', get_blog_page_by_year),
('^blog/(?P<year>\d{4})/(?P<month>\d{2})/$', get_posts_by_month),
('^blog/(?P<year>\d{4})/(?P<month>\d{2})/page/(?P<page>\d)/$', get_blog_page_by_month),
('^blog/(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/$', get_posts_by_day),
('^blog/tag/(?P<tag>[^/]+(?u))/$',tagged_object_list,dict(model=Blog_Model, paginate_by=1, \
allow_empty=True,template_object_name='blog_object', template_name='blog.html',\
('^blog/tag/(?P<tag>[^/]+(?u))/page/(?P<page>[0-9]+)/$',tagged_object_list,dict(model=Blog_Meta, \
 paginate_by=1, allow_empty=True, template_object_name='blog_object', template_name='blog.html',)),

By doing so we will be accepting all urls like

/blog/                       # the first page with latest items
/blog/2007/                  # the first page of all blog posts from 2007
/blog/2007/page/4/           # the fourth page of blog posts from 2007
/blog/2007/10/               # blog posts from October 2007
/blog/2007/09/page/2/        # the second page from November 2007
/blog/2007/11/15/            # the post on 15 November 2007
/blog/tag/django/            # Posts with tag django
/blog/tag/django/page/7/     # Seventh page with tag django

Django provides a date-based generic view that saves us from the writing views for date filtering etc. But date-based generic views do not provide pagination by default. But django is powerful and highly extensible. It provides an Object Paginator which can be used for paginations. So I will use a list-based generic view to mimic the date-based generic views with pagination. Open the views.py file in blog_app and paste the following code.

 from django.core.paginator import ObjectPaginator
 from blog_app.models import Blog_Model
 from django.http import HttpResponse, Http404
 from django.template import loader, Context
 from django.views.generic.date_based import archive_day
 from django.views.generic.list_detail import object_list
 import tagging

 # Number of Entries per page (paginate_by)
 num_entries_per_page = 7

 def get_blog_page(request,page):
     queryset = Blog_Model.objects.order_by("-blog_date_pub")
     paginator = ObjectPaginator(queryset, num_entries_per_page)
     cloud_list = tagging.models.Tag.objects.cloud_for_model(Blog_Model,steps=2)
     if int(page) in paginator.page_range:
         return object_list(request,queryset,num_entries_per_page,page,template_name='blog.html',\
         template_object_name='blog_object',extra_context={'cloud_list': cloud_list,})
         raise Http404

 def get_blog_first_page(request):
     return get_blog_page(request,1)

 def get_blog_page_by_year(request,year,page):
     queryset = Blog_Model.objects.filter(**{"blog_date_pub__year":year}).order_by("-blog_date_pub")
         assert queryset
     except AssertionError:
         raise Http404
     paginator = ObjectPaginator(queryset, num_entries_per_page)
     cloud_list = tagging.models.Tag.objects.cloud_for_model(Blog_Model,steps=2)
     if int(page) in paginator.page_range:
         return object_list(request,queryset,num_entries_per_page,page,template_name='blog.html',\
         template_object_name='blog_object',extra_context={"year":year,'cloud_list': cloud_list,})
         raise Http404

def get_posts_by_year(request, year):
    return get_blog_page_by_year(request,year,1)

def get_posts_by_day(request,year,month,day):
    month_dict = {1:"Jan",2:"Feb",3:"Mar",4:"Apr",5:"May",6:"Jun",7:"Jul",8:"Aug",\
       month_name = month_dict[int(month)]
       except ValueError:
          raise Http404
    cloud_list = tagging.models.Tag.objects.cloud_for_model(Blog_Model,steps=2)
    return archive_day(request,year,month_name,day,Blog_Model.objects.all(),'blog_date_pub',\
    extra_context={'cloud_list': cloud_list,})

I have not given the complete view. You can check it out here. The next part in this series talks about templates.