-
-
Notifications
You must be signed in to change notification settings - Fork 24
Resolve #160 -- Add picture_processed signal
#231
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
81c6163
2621125
dbc80b3
1d6b82e
6cd32cd
cafec7e
67a476b
ed11b97
4077289
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,3 @@ | ||||||||||||||||||||||||
| import django.dispatch | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| picture_processed = django.dispatch.Signal() | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
| picture_processed = django.dispatch.Signal() | |
| picture_processed = django.dispatch.Signal() | |
| picture_processed.__doc__ = """ | |
| Signal sent when a picture has been processed. | |
| Parameters: | |
| sender: The sender of the signal (usually the model class). | |
| file_name (str): The name of the processed picture file. | |
| new (bool): True if the picture is newly processed, False if updated. | |
| old (bool): True if the picture existed before processing, False otherwise. | |
| """ |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -4,6 +4,7 @@ | |||||
| from django.core.management import call_command | ||||||
| from django.db import models | ||||||
| from django.db.models.fields.files import ImageFieldFile | ||||||
| from django.test.utils import isolate_apps | ||||||
|
|
||||||
| from pictures import migrations | ||||||
| from pictures.models import PictureField | ||||||
|
|
@@ -117,6 +118,7 @@ class Meta: | |||||
| assert not migration.to_picture_field.called | ||||||
|
|
||||||
| @pytest.mark.django_db | ||||||
| @isolate_apps | ||||||
|
||||||
| @isolate_apps | |
| @isolate_apps("testapp") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tried that initially, doesn't work.
Copilot
AI
Dec 1, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The @isolate_apps decorator requires an argument specifying the app label(s) to isolate. It should be used as @isolate_apps('app_label') or @isolate_apps('app1', 'app2'). Without an argument, this will not work as intended.
| @isolate_apps | |
| @isolate_apps("testapp") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tried that initially, doesn't work.
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,68 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from unittest.mock import Mock | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import pytest | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from django.dispatch import receiver | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from pictures import signals, tasks | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from tests.test_migrations import skip_dramatiq | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should probably be moved somewhere else. Otherwise, module-level fixtures will be unintentionally loaded too and introduce side effects. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from tests.testapp.models import SimpleModel | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @pytest.mark.django_db | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @skip_dramatiq | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def test_process_picture_sends_process_picture_done(image_upload_file): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| obj = SimpleModel.objects.create(picture=image_upload_file) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| handler = Mock() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| signals.picture_processed.connect(handler) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tasks._process_picture( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| obj.picture.storage.deconstruct(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| obj.picture.name, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| obj.picture.sender, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| new=[i.deconstruct() for i in obj.picture.get_picture_files_list()], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| handler.assert_called_once_with( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| signal=signals.picture_processed, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sender=SimpleModel._meta.get_field("picture"), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| file_name=obj.picture.name, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| new=[i.deconstruct() for i in obj.picture.get_picture_files_list()], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| old=[], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @pytest.mark.django_db | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @skip_dramatiq | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def test_process_picture_sends_process_picture_done_on_create(image_upload_file): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def test_process_picture_sends_process_picture_done_on_create(image_upload_file): | |
| def test_process_picture_sends_picture_processed_on_create(image_upload_file): |
Copilot
AI
Dec 1, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The signal handler should be disconnected after the test to prevent test pollution. Consider adding signals.picture_processed.disconnect(handler) in a try/finally block or use a pytest fixture for cleanup.
| tasks._process_picture( | |
| obj.picture.storage.deconstruct(), | |
| obj.picture.name, | |
| obj.picture.sender, | |
| new=[i.deconstruct() for i in obj.picture.get_picture_files_list()], | |
| ) | |
| handler.assert_called_once_with( | |
| signal=signals.picture_processed, | |
| sender=SimpleModel._meta.get_field("picture"), | |
| file_name=obj.picture.name, | |
| new=[i.deconstruct() for i in obj.picture.get_picture_files_list()], | |
| old=[], | |
| ) | |
| @pytest.mark.django_db | |
| @skip_dramatiq | |
| def test_process_picture_sends_process_picture_done_on_create(image_upload_file): | |
| handler = Mock() | |
| signals.picture_processed.connect(handler) | |
| obj = SimpleModel.objects.create(picture=image_upload_file) | |
| handler.assert_called_once_with( | |
| signal=signals.picture_processed, | |
| sender=SimpleModel._meta.get_field("picture"), | |
| file_name=obj.picture.name, | |
| new=[i.deconstruct() for i in obj.picture.get_picture_files_list()], | |
| old=[], | |
| ) | |
| try: | |
| tasks._process_picture( | |
| obj.picture.storage.deconstruct(), | |
| obj.picture.name, | |
| obj.picture.sender, | |
| new=[i.deconstruct() for i in obj.picture.get_picture_files_list()], | |
| ) | |
| handler.assert_called_once_with( | |
| signal=signals.picture_processed, | |
| sender=SimpleModel._meta.get_field("picture"), | |
| file_name=obj.picture.name, | |
| new=[i.deconstruct() for i in obj.picture.get_picture_files_list()], | |
| old=[], | |
| ) | |
| finally: | |
| signals.picture_processed.disconnect(handler) | |
| @pytest.mark.django_db | |
| @skip_dramatiq | |
| def test_process_picture_sends_process_picture_done_on_create(image_upload_file): | |
| handler = Mock() | |
| signals.picture_processed.connect(handler) | |
| try: | |
| obj = SimpleModel.objects.create(picture=image_upload_file) | |
| handler.assert_called_once_with( | |
| signal=signals.picture_processed, | |
| sender=SimpleModel._meta.get_field("picture"), | |
| file_name=obj.picture.name, | |
| new=[i.deconstruct() for i in obj.picture.get_picture_files_list()], | |
| old=[], | |
| ) | |
| finally: | |
| signals.picture_processed.disconnect(handler) |
Copilot
AI
Dec 1, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The signal handler should be disconnected after the test to prevent test pollution. Consider adding signals.picture_processed.disconnect(handler) in a try/finally block or use a pytest fixture for cleanup.
| tasks._process_picture( | |
| obj.picture.storage.deconstruct(), | |
| obj.picture.name, | |
| obj.picture.sender, | |
| new=[i.deconstruct() for i in obj.picture.get_picture_files_list()], | |
| ) | |
| handler.assert_called_once_with( | |
| signal=signals.picture_processed, | |
| sender=SimpleModel._meta.get_field("picture"), | |
| file_name=obj.picture.name, | |
| new=[i.deconstruct() for i in obj.picture.get_picture_files_list()], | |
| old=[], | |
| ) | |
| @pytest.mark.django_db | |
| @skip_dramatiq | |
| def test_process_picture_sends_process_picture_done_on_create(image_upload_file): | |
| handler = Mock() | |
| signals.picture_processed.connect(handler) | |
| obj = SimpleModel.objects.create(picture=image_upload_file) | |
| handler.assert_called_once_with( | |
| signal=signals.picture_processed, | |
| sender=SimpleModel._meta.get_field("picture"), | |
| file_name=obj.picture.name, | |
| new=[i.deconstruct() for i in obj.picture.get_picture_files_list()], | |
| old=[], | |
| ) | |
| try: | |
| tasks._process_picture( | |
| obj.picture.storage.deconstruct(), | |
| obj.picture.name, | |
| obj.picture.sender, | |
| new=[i.deconstruct() for i in obj.picture.get_picture_files_list()], | |
| ) | |
| handler.assert_called_once_with( | |
| signal=signals.picture_processed, | |
| sender=SimpleModel._meta.get_field("picture"), | |
| file_name=obj.picture.name, | |
| new=[i.deconstruct() for i in obj.picture.get_picture_files_list()], | |
| old=[], | |
| ) | |
| finally: | |
| signals.picture_processed.disconnect(handler) | |
| @pytest.mark.django_db | |
| @skip_dramatiq | |
| def test_process_picture_sends_process_picture_done_on_create(image_upload_file): | |
| handler = Mock() | |
| signals.picture_processed.connect(handler) | |
| try: | |
| obj = SimpleModel.objects.create(picture=image_upload_file) | |
| handler.assert_called_once_with( | |
| signal=signals.picture_processed, | |
| sender=SimpleModel._meta.get_field("picture"), | |
| file_name=obj.picture.name, | |
| new=[i.deconstruct() for i in obj.picture.get_picture_files_list()], | |
| old=[], | |
| ) | |
| finally: | |
| signals.picture_processed.disconnect(handler) |
Copilot
AI
Dec 1, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The signal handler registered with @receiver decorator is not cleaned up after the test completes. This could cause test pollution and interfere with other tests. Consider using a try/finally block or pytest fixture to ensure the handler is disconnected after the test, or use .connect() with manual cleanup instead of the decorator.
| @receiver(signals.picture_processed, sender=SimpleModel._meta.get_field("picture")) | |
| def handler(*, sender, file_name, **__): | |
| nonlocal found_object | |
| # Users can now modify the object that picture_processed corresponds to | |
| found_object = sender.model.objects.get(**{sender.name: file_name}) | |
| obj.picture.save("image.png", image_upload_file) | |
| def handler(*, sender, file_name, **__): | |
| nonlocal found_object | |
| # Users can now modify the object that picture_processed corresponds to | |
| found_object = sender.model.objects.get(**{sender.name: file_name}) | |
| signals.picture_processed.connect(handler, sender=SimpleModel._meta.get_field("picture")) | |
| try: | |
| obj.picture.save("image.png", image_upload_file) | |
| finally: | |
| signals.picture_processed.disconnect(handler, sender=SimpleModel._meta.get_field("picture")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm… we should probably pass the model
instanceto the signal, just like the post- or pre-save signals.Your filename doesn't need to be unique. It should, but it really doesn't have to.
However, this would mean fetching it from the DB in the processing task. I'd love to avoid DB IO in the processing task by default.
If you add a unique constraint and index, including a comment on why they matter, that might be the best solution. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An index makes sense for the lookup here, but I'm not sure if a unique constraint is strictly necessary.
filterwill update all rows that match. I think that makes sense as I think that the variations would have been removed for that file.To send along the instance we would need acceess to it to serialize it. Accessing the instance in https://github.com/jmsmkn/django-pictures/blob/4077289ae6a75c8f8a810d04487af4a95b4f1a45/pictures/models.py#L179-L185 doesn't work as Django cleanup assigns a fake instance to
self.instance. I don't think that there is another workaround for that throughself.field.