Reputation:
I Have model fields as illustrated below:-
user=models.ForeignKey(CustomUser, null=True)
_corporate = models.CharField(max_length=10, null=True, db_column='corporate')
def set_corporate(self,value):
if self.user.corporateuser_set.all():
self._corporate = self.user.corporateuser_set.values_list('company', flat=True)
corporate= property(set_corporate)
Somehow, set_corporate is not being evaluated and therefore _corporate field is not updated.
So what should I do to make it work? what's the best approach here?
I have another model(CorporateUser) with a one to many relationship with User Model, just to clarity of my question.
Upvotes: 2
Views: 3172
Reputation: 3045
Your are doing it wrong in so many ways.
First, properties are used this way in python:
class A:
@property
def foo(self):
return self._foo
@foo.setter
def foo(self, value):
self._foo = value
Or this way:
class A:
def get_foo(self):
return self._foo
def set_foo(self, value):
self._foo = value
foo = property(get_foo, set_foo)
Note how value is passed to setter. It should not be computed there as you do. If you need to autoupdate corporate value then you don't need a property, you should overwrite models .save()
method or listen to its pre_save
signal and update field there.
Second, you should not conditionally set in setter. Setter should always set property to value passed. Like this:
def set_corporate(self, value):
# If the list is empty then corporate becomes empty
self._corporate = \
self.user.corporateuser_set.values_list('company', flat=True)
By violating this rule you will cause grief:
obj.corporate = 'hi'
# obj.corporate is now 'hi'
obj.corporate = ''
# obj.corporate is still 'hi'. WTF?
Third, you should not assign list
to CharField
. How this supposed to work? It will probably stringify it.
Forth, you are not even assigning a list, you are assigning queryset, which is worse.
Fifth, you are doing essentially same database request twice in a two lines. The efficient way to check if that is empty and then assign is by reusing same queryset:
corporates = self.user.corporateuser_set.values_list('company', flat=True)
if corporates:
# Stringify it explicitly and our way
self._corporate = ','.join(corporates)
Upvotes: 2
Reputation: 599470
That's not how you use properties. The first argument to the property
function, if you use it like that, is the getter method. You haven't even provided a getter method. You need one which returns the value of self._corporate
.
Upvotes: 0