Monday, 22 September 2008

10. Finishing the Code-Sharing Application

This is part 10 of a series of posts on James Bennett's excellent Practical Django Projects. The table of contents and explanation can be found here

Finally, we're on the home stretch. This chapter builds on our knowledge of templates and also gives a few new examples of custom template tags, so without further ado lets finish the app.

On p188 you need to modify the save method of the bookmark model to
#cab.models.py
...
  def save(self, force_insert=False, force_update=False):
      if not self.id:
          self.date = datetime.datetime.now()
      super(Bookmark, self).save(force_insert, force_update)
The force_insert and force_update keywords are new to 1.0. I'm not sure why they are specifically required in this model but I got an error without them and certainly the documentation shows that you include them if you override the save method. I guess this means that wherever you have overridden the save method you would include these arguments as best practice, but you can take a shortcut and write it like this:
#cab.models.py
...
  def save(self, **kwargs):
      if not self.id:
          self.date = datetime.datetime.now()
      super(Bookmark, self).save(**kwargs)
This will make your code safe if any of these model save method arguments are changed or added to, so go and add them to your rating and snippet models as well.

On p191 def user_bookmarks(request) is missing request in the object_list method call:
#cab.views.bookmarks.py
...
def user_bookmarks(request):
 return object_list(request, queryset=Bookmark.objects.filter(user__pk=request.user.id),
  template_name='cab/user_bookmarks.html',
  paginate_by=20)
Also on p191 the most_bookmarked method is missing a } after params and should read:
return self.extra(select={ 'score': subquery % params },
 order_by=['-score'])
After writing up the bookmarks templatetags code make yourself a simple bookmarks list template user_bookmarks.html once you get to p198 and the start of the User Rating System.
{% for bookmark in object_list %}
 <p><a href="{{ bookmark.snippet.get_absolute_url }}">{{ bookmark.snippet.title }}</a></p>
{% endfor %}

On p204 the template code for the ratings tag:
{% load snippets %}
{% if_rated user object %}
{% get_rating user snippet as rating %}
should read
{% load snippets %}
{% if_rated user object %}
{% get_rating user object as rating %}
This is because the snippet_detail.html template generic view uses object as the default template context.

That's it. You should now have a working basic snippets application with bookmarking and ratings working, and hopefully feel more comfortable working with Django. The final chapter of the book talks about re-usable apps, and gives some code but is focused on techniques rather than a fully working app, so I won't do any notes on it. I might write one more post just to summarize my own experiences with the book and Django as someone who has gone through it without any prior Django experience, but essentially that's all I have to offer on Practical Django Projects. I hope you've enjoyed it as much as I did, and I am looking forward to James releasing his sample code which should be the icing on the cake if you want to take any of these sample apps further.

3 comments:

Fernando Correia said...

Thank you so much for sharing this work. It helped me a lot while going through this book.

muchomuchacho said...

Thank you very much for the work done here. It was really helpful.

Gurur said...

I had to change this row "if Bookmark.objects.filter(user__pk=user.id, snippet__pk=snippet.id):" to "if Bookmark.objects.filter(user__pk=user, snippet__pk=snippet):"

Then it works for me but don't know if I have done something else wrong. ;)

Hedged Down