Sunday, March 27, 2011

Issues using django-compress and django.contrib.staticfiles from django 1.3

There is no way to use both django-compress and django.contrib.staticilfes from new django 1.3. MEDIA_URL and MEDIA_ROOT hardcoded into django-compress utility functions so here is
my fork of django-compress on github with fix.

I've added two new settings COMPRESS_URL and COMPRESS_ROOT which points by default to MEDIA_URL and MEDIA_ROOT respectively for backward compatibility.

django-compress is extremely useful tool which provide possibility to organize your JavaScript and CSS files around your project. Also there is a couple of useful features like support of YUI compressor and building of bunch of JavaScript or CSS files into one.

Read more about django-compress

direct_to_template generic view class-based replacement for django 1.3

I was in love with direct_to_template shortcut from django.views.generic.simple

Update: It was my lack of attention to the docs. new render shortcut do the same thing as code below

It's extremely useful to use direct_to_template instead of render_to_response because there is no necessary to put RequestContext to direct_to_template shourcut. But now it's deprecated so I decided to replace it with small class-based view which do same thing as old direct_to_template but – without restriction of new TemplateView where is no way to put extra context.

from django.views.generic.base import TemplateResponseMixin
from django.template import RequestContext


class RenderTemplate(TemplateResponseMixin):
    """django 1.3+ Class-Based replacement for
       django.views.generic.simple.direct_to_template
       Usage:
        context = {}
        return RenderTemplate.view(context, \
            request=request, template_name="main.html")
    """
    @classmethod
    def view(cls, context, render_args={}, **initkwargs):
        obj = cls()
        for key, val in initkwargs.iteritems():
            setattr(obj, key, val)

        return obj.render_to_response(context, **render_args)

    def render_to_response(self, context, **kwargs):
        return super(RenderTemplate, self)\
                    .render_to_response(RequestContext(self.request, \
                        context), **kwargs)

Wednesday, March 2, 2011

Disqus experience - cache of model's related fields

Very interesting tricks from Disqus: Scaling The World’s Largest Django Application

The main idea to retrieve related fields by two requests instead of 1 + 25 sql requests using post.user

Such situation caused in several projects simultaneously so I working on optimization things right now.

# cache
posts = Post.objects.all()[0:25]

users = dict(
    (u.pk, u) for u in \
    User.objects.filter(pk__in=set(p.user_id for p in posts))
)

for p in posts:
    p.__user_cache = users.get(p.user_id)


And don't forget about SQL indexes - in all cases when field used in ORDER or WHERE sql statements it will increase performance a lot