Why a model instance accessed from a @property can't mutate?

Hello! I have the following code which I’ve been using for my test cases:

class MyAppTestCase(TestCase):

    @property
    def my_model(self) -> MyModel:
        return MyModel.objects.get(user=self.user)   # (self.user is defined in the setUp)

    def seed_models(self):
        self.my_model.attribute = 'hello'
        print(self.my_model.attribute)  # <- prints None

But, if I declare MyModel instance in the setUp like:

    def setUp(self):
        super().setUp()
        self.my_model = MyModel.objects.get(user=self.user)

Then I can make self.my_model mutate!

    def seed_models(self):
        self.my_model.attribute = 'hello'
        print(self.my_model.attribute)  # <- prints "hello"

Why does this behavior occur? I know Django queries are lazies, but can someone explain further?
My decision to access it from a @property was in order to always have an updated instance of MyModel (since this class is just an utility class to inherit in concrete test case classes)

That is the specific purpose and intent of the @property decorator. It creates a read-only attribute by that name in the class.

See the docs for more details.

1 Like