Showing posts with label django. Show all posts
Showing posts with label django. Show all posts

Wednesday, 21 December 2011

Different ways for low level caching in Django

Often in a Django projects complex data processing can be involved in order to get desire output. It can be a good idea to use some kind of caching. Django provides a robust cache system. It's possible to store and retrieve wide range of data with different level of complexity.
Most easiest ways to use caching is to use:

But I'm more interested in mixing two other types of caching:
Trivial examples of them can be found at Caching websites with Django and Memcached…
But what if on the one hand we have some complex python code which give us a complex output (like dict, or list of dicts, or something like this) and on the other hand this complex output is used in the template for another complex work (e.g., building table with many dependencies).
How to deal with such cases?

Just use both of them

That is, complex output is cached in the python code and there is cached fragment in the template.
Pros: simple enough
Cons: if the cache key used in the python code is expired, the complex calculation will be made in order to get the complex result. But the key used for template fragment might haven't expired, so the efforts are wasted.

Do the hard work, only if it's needed

Not only the key used in the python code should be checked, but also the one generated for the cached template fragment. If the last one is not expired, the hard work can be skipped.

Pros: complex calculations are performed only when they are really needed
Cons: additional code is needed in order to generate same key as the one used by {% cache %} template tag. There is no guarantee that this key will be generated in the same way in the next Django version.

Cache only the final result

Save your template fragment that should be cached in separate template file. When you get your complex output form your hard calculations use render_to_string to get desire result and put it in the cache. The result is string, which can be used 'as is' in the template.

I will be glad to hear your opinion on the topic.

Saturday, 7 May 2011

At least one field of the form is required

Suppose we have a form to collect user data and three of the fields are for contact details - mail, phone and fax. We want users to fill with valid data at least one of them. In other words they must have required=False and their validation should be done both in clean_FIELDNAME() and clean(). Usually in order to check whether a field has a fair value, we check in cleaned_data keys. But these fields are not mandatory and they always will be present in cleaned_data, even when they are empty. Therefore we need to verify not only the keys but also the values. I propose the following simple solution:
clnd_data = super(MyForm, self).clean()
cnts = ['email','phone','fax']
if not [k for k in cnts if clnd_data.get(k, '').strip()]:
    raise forms.ValidationError(_(u'Please enter at least one.'))
return clnd_data

Ilian proposed different approach:

clnd_data = super(MyForm, self).clean()
cnts = ['email','phone','fax']
if any([f for f in cnts if clnd_data.get(f, None)]):
    return clnd_data
else:
   raise forms.ValidationError(_('Please ...'))

Wednesday, 2 March 2011

Having global variable in your django templates

This post is based on question in stackoverflow.com
The question is about having 'now' in blocktrans.
In blocktrans we can't use templatetags so we will assign result of the templatetags to a variable, like this:
 {% url "add_account" as add_account_url %}

But 'now' doesn't act the same way.