Skip to content

Commit 27c2121

Browse files
committed
Merge pull request #17 from nyaruka/master
DB Optimization for save and validate
2 parents 24be357 + 2b8eaf9 commit 27c2121

1 file changed

Lines changed: 35 additions & 7 deletions

File tree

eav/models.py

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -443,13 +443,27 @@ def get_all_attributes(self):
443443
'''
444444
return self.model._eav_config_cls.get_attributes()
445445

446+
def _hasattr(self, attribute_slug):
447+
'''
448+
Since we override __getattr__ with a backdown to the database, this exists as a way of
449+
checking whether a user has set a real attribute on ourselves, without going to the db if not
450+
'''
451+
return attribute_slug in self.__dict__
452+
453+
def _getattr(self, attribute_slug):
454+
'''
455+
Since we override __getattr__ with a backdown to the database, this exists as a way of
456+
getting the value a user set for one of our attributes, without going to the db to check
457+
'''
458+
return self.__dict__[attribute_slug]
459+
446460
def save(self):
447461
'''
448462
Saves all the EAV values that have been set on this entity.
449463
'''
450464
for attribute in self.get_all_attributes():
451-
if hasattr(self, attribute.slug):
452-
attribute_value = getattr(self, attribute.slug)
465+
if self._hasattr(attribute.slug):
466+
attribute_value = self._getattr(attribute.slug)
453467
attribute.save_value(self.model, attribute_value)
454468

455469
def validate_attributes(self):
@@ -459,20 +473,34 @@ def validate_attributes(self):
459473
460474
Raise ``ValidationError`` if they can't be.
461475
'''
476+
values_dict = self.get_values_dict()
477+
462478
for attribute in self.get_all_attributes():
463-
value = getattr(self, attribute.slug, None)
479+
value = None
480+
if self._hasattr(attribute.slug):
481+
value = self._getattr(attribute.slug)
482+
else:
483+
value = values_dict.get(attribute.slug, None)
484+
464485
if value is None:
465486
if attribute.required:
466487
raise ValidationError(_(u"%(attr)s EAV field cannot " \
467-
u"be blank") % \
468-
{'attr': attribute.slug})
488+
u"be blank") % \
489+
{'attr': attribute.slug})
469490
else:
470491
try:
471492
attribute.validate_value(value)
472493
except ValidationError, e:
473494
raise ValidationError(_(u"%(attr)s EAV field %(err)s") % \
474-
{'attr': attribute.slug,
475-
'err': e})
495+
{'attr': attribute.slug,
496+
'err': e})
497+
498+
def get_values_dict(self):
499+
values_dict = dict()
500+
for value in self.get_values():
501+
values_dict[value.attribute.slug] = value.value
502+
503+
return values_dict
476504

477505
def get_values(self):
478506
'''

0 commit comments

Comments
 (0)