Reputation: 11118
I have a Django 1.5 app with a custom User
model. It has the following field (among a bunch of others):
class User(models.Model):
...
reporting_period = models.CharField(
max_length=20,
choices=REPORTING_PERIODS,
null=True,
blank=True,
default=None
)
company = models.ForeignKey(
Company,
null=True,
blank=True,
default=None
)
This model also has the following function defined:
def get_reporting_period(self, company_reporting_period=None):
if not self.reporting_period:
if not hasattr(self, '_company_reporting_period'):
if company_reporting_period:
self._company_reporting_period = company_reporting_period
else:
self._company_reporting_period = self.company.reporting_period
return self._company_reporting_period
else:
return self.reporting_period
Occasionally, the get_reporting_period
function throws an AttributeError ('User' object has no attribute 'reporting_period') on the line if not self.reporting_period:
. I am scratching my head as to how that is possible.
self
is a User
instance, and therefore should have a reporting_period
at all times. Are there any times during a model instance's lifetime in Django when a field is not accessible as a property?
Unfortunately, the issue only happens in my production environment where I am unable to debug it.
Upvotes: 0
Views: 58
Reputation: 53699
Field attributes on instances are not defined until the __init__
method of the Model
class is called. Trying to access a field attribute in a custom __init__
method before calling the super method will result in an AttributeError
.
Otherwise something must've accidentally deleted the attribute on the instance.
I believe that are the only two instances when a field attribute is not defined on a model instance.
EDIT: I've done a small test, and unpickling preserves the attributes of the original version of the model, but new methods carry over to the recreated model. So you would be able to call the new get_reporting_period
function, but it would raise an AttributeError
when trying to access the undefined reporting_period
attribute.
That means that in this case you should invalidate your cached entries after adding a new field. However, there are plenty of serialization methods that would not result in such an error. Take a look at the answer to this question for a way to serialize models without this problem.
Upvotes: 1