rsinger86/django-lifecycle

'NoneType' object has no attribute 'seek' on saving a model with ImageField

Closed this issue ยท 5 comments

Hello, the following code is related to my model and when I add the LifecycleModelMixin mixin to it and I want to save the model along with the image field, I get the following error:

models.py

class Expenses(LifecycleModelMixin, AbstractModel):
    id = models.UUIDField(
        primary_key=True,
        editable=False,
        unique=True,
        default=uuid.uuid4,
    )
    paid_by = models.ForeignKey(
        to='account.User',
        on_delete=models.CASCADE,
        related_name='expenses',
    )
    amount = models.PositiveBigIntegerField()
    description = models.CharField(max_length=50)
    is_initial = models.BooleanField(default=False)
    date = models.DateTimeField(default=timezone.now)
    image = models.ImageField(
        upload_to='expenses/',
        null=True,
        blank=True
    )
    
    @hook(AFTER_CREATE)
    def send_notification(self):
        text = _(
            '{paid_by} registered {amount} tomans'
            ' for "{expense_description}".'
        ).format(
            paid_by=self.paid_by.get_full_name(),
            amount=intcomma(self.amount, use_l10n=False),
            expense_description=self.description,
        )

        for id_ in event_participates_ids:
            send_notification_task.delay(
                user_id=id_,
                type='in_app',
                text=text,
                section=NotificationSections.EXPENSES,
                from_user=self.paid_by.id,
            )

Error:

Traceback (most recent call last):
  File "C:\Users\mazarian\Documents\Python-projects\dangdong_backend\venv\lib\site-packages\PIL\ImageFile.py", line 202, in load
    seek = self.load_seek
AttributeError: 'PngImageFile' object has no attribute 'load_seek'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\mazarian\Documents\Python-projects\dangdong_backend\venv\lib\site-packages\django\core\handlers\exception.py", line 55, in inner
    response = get_response(request)
  File "C:\Users\mazarian\Documents\Python-projects\dangdong_backend\venv\lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\mazarian\Documents\Python-projects\dangdong_backend\venv\lib\site-packages\django\views\decorators\csrf.py", line 56, in wrapper_view
    return view_func(*args, **kwargs)
  File "C:\Users\mazarian\Documents\Python-projects\dangdong_backend\venv\lib\site-packages\rest_framework\viewsets.py", line 125, in view
    return self.dispatch(request, *args, **kwargs)
  File "C:\Users\mazarian\Documents\Python-projects\dangdong_backend\venv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
    response = self.handle_exception(exc)
  File "C:\Users\mazarian\Documents\Python-projects\dangdong_backend\venv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
    self.raise_uncaught_exception(exc)
  File "C:\Users\mazarian\Documents\Python-projects\dangdong_backend\venv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
    raise exc
  File "C:\Users\mazarian\Documents\Python-projects\dangdong_backend\venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
  File "C:\Users\mazarian\Documents\Python-projects\dangdong_backend\venv\lib\site-packages\drf_spectacular\drainage.py", line 207, in wrapped_method
    return method(self, request, *args, **kwargs)
  File "C:\Users\mazarian\Documents\Python-projects\dangdong_backend\venv\lib\site-packages\rest_framework\mixins.py", line 19, in create
    self.perform_create(serializer)
  File "C:\Users\mazarian\Documents\Python-projects\dangdong_backend\events\api\v1\views.py", line 392, in perform_create
    models.Expenses
  File "C:\Users\mazarian\Documents\Python-projects\dangdong_backend\venv\lib\site-packages\django\db\models\manager.py", line 87, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "C:\Users\mazarian\Documents\Python-projects\dangdong_backend\venv\lib\site-packages\django\db\models\query.py", line 656, in create
    obj = self.model(**kwargs)
  File "C:\Users\mazarian\Documents\Python-projects\dangdong_backend\venv\lib\site-packages\django_lifecycle\mixins.py", line 83, in __init__
    self._initial_state = self._snapshot_state()
  File "C:\Users\mazarian\Documents\Python-projects\dangdong_backend\venv\lib\site-packages\django_lifecycle\mixins.py", line 86, in _snapshot_state
    state = deepcopy(self.__dict__)
  File "C:\Users\mazarian\AppData\Local\Programs\Python\Python310\lib\copy.py", line 146, in deepcopy
    y = copier(x, memo)
  File "C:\Users\mazarian\AppData\Local\Programs\Python\Python310\lib\copy.py", line 231, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "C:\Users\mazarian\AppData\Local\Programs\Python\Python310\lib\copy.py", line 172, in deepcopy
    y = _reconstruct(x, memo, *rv)
  File "C:\Users\mazarian\AppData\Local\Programs\Python\Python310\lib\copy.py", line 271, in _reconstruct
    state = deepcopy(state, memo)
  File "C:\Users\mazarian\AppData\Local\Programs\Python\Python310\lib\copy.py", line 146, in deepcopy
    y = copier(x, memo)
  File "C:\Users\mazarian\AppData\Local\Programs\Python\Python310\lib\copy.py", line 231, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "C:\Users\mazarian\AppData\Local\Programs\Python\Python310\lib\copy.py", line 161, in deepcopy
    rv = reductor(4)
  File "C:\Users\mazarian\Documents\Python-projects\dangdong_backend\venv\lib\site-packages\PIL\Image.py", line 712, in __getstate__
    im_data = self.tobytes()  # load image first
  File "C:\Users\mazarian\Documents\Python-projects\dangdong_backend\venv\lib\site-packages\PIL\Image.py", line 755, in tobytes
    self.load()
  File "C:\Users\mazarian\Documents\Python-projects\dangdong_backend\venv\lib\site-packages\PIL\ImageFile.py", line 205, in load
    seek = self.fp.seek
AttributeError: 'NoneType' object has no attribute 'seek'

Can you try to downgrade to 1.1.2 and check if it works?

Can you try to downgrade to 1.1.2 and check if it works?

Yes, it works, but with this version you cannot use "condition" in hooks (legacy only) :(

Can you try to downgrade to 1.1.2 and check if it works?

Yes, it works, but with this version you cannot use "condition" in hooks (legacy only) :(

I will try to find some time to fix it, and if not I'm considering reverting the commit that caused this bug.

Out of curiosity, what do you want to achieve with conditions that's not available with legacy condition?

I bumped into this today, it seems related to PIL:

So you need to reopen the Image attached to the ImageField. I did something like this:

image_field.image = Image.open(image_field)
MyModel.objects.create(image=image_field)

Hope it helps.

Solved in #161, which will be included in version 1.2.4