Attribute Cache in Django - What's the point?

django, django-models, python

Solution

I don't know why this is an IntegerField; it looks like it definitely should be a ForeignKey(User) field--you lose things like select_related() here and other things because of that, too.

As to the caching, many databases don't cache results--they (or rather, the OS) will cache the data on disk needed to get the result, so looking it up a second time should be faster than the first, but it'll still take work.

It also still takes a database round-trip to look it up. In my experience, with Django, doing an item lookup can take around 0.5 to 1ms, for an SQL command to a local Postgresql server plus sometimes nontrivial overhead of QuerySet. 1ms is a lot if you don't need it--do that a few times and you can turn a 30ms request into a 35ms request.

If your SQL server isn't local and you actually have network round-trips to deal with, the numbers get bigger.

Finally, people generally expect accessing a property to be fast; when they're complex enough to cause SQL queries, caching the result is generally a good idea.

Problem

I was just looking over EveryBlock's source code and I noticed this code in the alerts/models.py code: ``` def _get_user(self): if not hasattr(self, '_user_cache'): from ebpub.accounts.models import User try: self._user_cache = User.objects.get(id=self.user_id) except User.DoesNotExist: self._user_cache = None return self._user_cache user = property(_get_user) ``` I've noticed this pattern around a bunch, but I don't quite understand the use. Is the whole idea to make sure that when accessing the FK on self (self = alert object), that you only grab the user object once from the db? Why wouldn't you just rely upon the db caching amd django's ForeignKey() field? I noticed that the model definition only holds the user id and not a foreign key field: ``` class EmailAlert(models.Model): user_id = models.IntegerField() ... ``` Any insights would be appreciated.

Original source