enapupe
enapupe

Reputation: 17019

python variable reference unexpectedly changing behaviour

I'd like to understand what's the cause of this totally unexpected change of behaviour and how it could be implemented. I come from JS world and this is very likely to be impossible to implement in any way..

Calling a fn by traversing an object gets a different result from when this object is first assigned to a new variable:

>>> from core.models import SomeModel
>>> s = SomeModel.objects.get(id=45)
>>> s.user.profile.needs_review
True
>>> s.user.profile.needs_review = False
>>> s.user.profile.needs_review
True
>>> profile = s.user.profile
>>> profile.needs_review
True
>>> profile.needs_review = False
>>> profile.needs_review
False

This is really disturbing because in any language I've worked with this would execute likewise.

BTW, this is a regular django model but I'm more interested in knowing what kind of language resources can be used to accomplish such effect.

To better explain why I got into this, I was trying to do a regular save on the profile model by doing:

streamer.user.profile.needs_review = True
streamer.user.profile.save()

And it didn't worked, but doing:

profile = streamer.user.profile
profile.needs_review = True
profile.save()

worked just fine.

Upvotes: 2

Views: 71

Answers (2)

joaoricardo000
joaoricardo000

Reputation: 4939

About the python language resource that allows this behavior, you can check this:
https://docs.python.org/3/library/functions.html#property

class C:
    def __init__(self):
        self._x = None

    @property
    def x(self):
        """I'm the 'x' property."""
        return self._x

    @x.setter
    def x(self, value):
        self._x = value

    @x.deleter
    def x(self):
        del self._x

Basically, django uses this to abstract the database queries and does not behave as a regular object in your example.

Upvotes: 1

Arpit Solanki
Arpit Solanki

Reputation: 9931

You have to save a model object if you make changes to it otherwise it won't reflect.

>>> s.user.profile.needs_review = False
>>> s.save()
>>> s.user.profile.needs_review
False

The line below

>>> profile = s.user.profile
>>> profile.needs_review
True

It does not load new data from database So that's why you see this behaviour

Upvotes: 1

Related Questions