I have two model like this with following fields:
Profile: -user(OTO Relation to User) -address(OTO to Address) -bio -gender ... Address: -postal_code -phone_number -zip_code
I Also I have this list of fields name:
my_list = ["bio","gender","address.postal_code","address.phone_number", "address.zip_code"]
And finally I want to I create this @property
:
@property def is_complete_profile(self): ''' Checks if all the fields have been filled ''' if self.pk: for field_name in my_list: value = getattr(self,field_name) if not value: return False return True else: return False
But for related objects
this isn’t the correct way and I got this error:
‘Profile’ object has no attribute ‘address.postal_code’
How Can I use this list for get value of field of Profile
objects and related object values?
Notice:
I could solve this problem by using
eval
function, but because of this and this post, I preferred to throw this solution away.
Advertisement
Answer
Rather than having Profile
nose around in its peers’ internals, I would give each class involved an is_complete
property (or method) which determines if the instance is complete, and have Profile.is_complete_profile
access those properties to determine if the profile is totally complete.
Something like this (untested)
class Address: def is_complete(self): fields = ["postal_code", "phone_number", "zip_code"] for field in fields: if not getattr(self, field): return False return True class Profile: def is_complete(self): fields = ["bio","gender"] for field in fields: if not getattr(self, field): return False return True @property def is_complete_profile(self): ''' Checks if all the fields have been filled ''' if self.pk: return self.is_complete() and self.address.is_complete() return False
This way Profile
doesn’t need to change if the names of Address
‘s fields change, and only minimal changes are required if additional objects get added to the notion of “completeness”.