django-fsm icon indicating copy to clipboard operation
django-fsm copied to clipboard

`Model.refresh_from_db` doesn't work with protected option

Open Nnonexistent opened this issue 8 years ago • 4 comments

If there is FSMField field with protected=True in django model then refresh_from_db method will fail with AttributeError exception.

class ProtectedAccessModel(models.Model):
    status = FSMField(default='new', protected=True)

instance = ProtectedAccessModel()
instance.save()
instance.refresh_from_db()  # <-- AttributeError will be raised

Nnonexistent avatar May 19 '17 14:05 Nnonexistent

For my point of view this is a major issue. refresh_from_db used widely and supposed to work in any cases.

Nnonexistent avatar May 19 '17 14:05 Nnonexistent

duplicate of #89 and documented in #91, although i would definitely appreciate the fix you provide in your PR.

karyon avatar Jun 06 '17 11:06 karyon

As you can see the solution fastly became too complicated.

kmmbvnr avatar Jun 08 '17 09:06 kmmbvnr

This is my current overridden refresh_from_db that I use for a workaround. This is for a model that has a single django-fsm field named status:

    def refresh_from_db(self, using=None, fields=None):
        """
        Reload instance from database
        but avoid writing to self.status, directly.
        """
        if fields is None:
            refresh_status = True
            fields = [f.name for f in self._meta.concrete_fields]
        else:
            refresh_status = 'status' in fields

        fields_without_status = [f for f in fields if f != 'status']

        with transaction.atomic():
            super().refresh_from_db(using=using, fields=fields_without_status)

            if refresh_status:
                fresh_status = type(self).objects.only('status').get(pk=self.pk).status
                self._meta.get_field('status').set_state(self, fresh_status)

moseb avatar Dec 06 '19 11:12 moseb

Since all possible solutions are hacky and thread/async unsafe this one of the reason why the alternative fsm implementation was created

https://docs.viewflow.io/fsm/index.html

kmmbvnr avatar Dec 21 '23 08:12 kmmbvnr