In the above snippet, if the call to get returns an empty collection the
cached result is ignored and the value is recalculated unnecessarily.
Avoid this by explicitly comparing the return value to None:
cached = cache.get(cache_key)
if cached is not None: # much better!
return cached
Django's documentation wisely advises against caching the literal value None,
and the above snippet makes it clear why this is good advice – the get method
returns None when the cache does not contain an entry for the supplied key.
class SubdomainMiddleware:
def process_request(self, request):
'''Parse out the subdomain from the request'''
request.subdomain = None
host = request.META.get('HTTP_HOST', '')
host_s = host.replace('www.', '').split('.')
if len(host_s) > 2:
request.subdomain = ''.join(host_s[:-2])
Initially I replaced test.com with the site's domain name, but I decided
that it's useful to be able to access both the live site and the test site
without editing the /etc/hosts file.
At this point I expected everything to work as advertised. Instead, I got
this:
That would depend on one's definition of "works". I wanted my Django site
to appear, which required a very simple tweak…
I wanted to simplify everything. I wanted to write posts in Markdown,
not HTML. I wanted to save posts as files, not database entries. I wanted to
free myself of my dependence on WordPress, PHP, and MySQL in one fell swoop.
So, Mango was born. Mango is file-based blogging software built on
Django, the excellent Python web framework. I conceived Mango to
scratch an itch, and I'll bet that others out there are itchy, too.
One might expect the following code to serialize a Django model instance:
import simplejson
simplejson.dumps(instance)
Unforunately, this raises a TypeError, as the instance is not JSON
serializable. I don't understand why model instances are not serializable,
but I do have a solution: define a serialization method on the instance's
model.
def toJSON(self):
import simplejson
return simplejson.dumps(dict([(attr, getattr(self, attr)) for attr in [f.name for f in self._meta.fields]]))
Here's the verbose equivalent for those averse to one-liners:
def toJSON(self):
fields = []
for field in self._meta.fields:
fields.append(field.name)
d = {}
for attr in fields:
d[attr] = getattr(self, attr)
import simplejson
return simplejson.dumps(d)
_meta.fields is an ordered list of model fields which can be accessed from
instances and from the model itself. _meta.fields is one of the few
features not covered in Django's excellent documentation.
>>> print [f.name for f in m._meta.fields]
['id', 'first_name', 'last_name', 'instrument']
This approach also works on models directly:
>>> print [f.name for f in Musician._meta.fields]
['id', 'first_name', 'last_name', 'instrument']
Advantages of using _meta.fields
items in returned list are correctly ordered
applicable to both models and instances
only fields are returned
The fact that only fields are returned is extremely useful. Django appears
to add its own attributes to instances in certain circumstances; using
_meta.fields prevents these from interfering with one's own code.
I love Coda. It's just so… sexy, somehow. I've just discovered
Django, with which I'm fast falling in love as well. Naturally, when I
came to write my first Django template I opened Coda.app and started coding.