Skip to content
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

Fixed signals can not connect to OneToOneField (#572) #573

Merged
merged 9 commits into from
Oct 13, 2022

Conversation

954-Ivory
Copy link
Contributor

@954-Ivory 954-Ivory commented Aug 21, 2022

Incidentally, the file storage of the signal has been changed.

@lgtm-com
Copy link

lgtm-com bot commented Aug 21, 2022

This pull request introduces 1 alert when merging b99abe3 into d4b97af - view on LGTM.com

new alerts:

  • 1 for Unused import

@@ -0,0 +1,41 @@
def signals_connect():
from django.db.models import signals, OneToOneRel
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OneToOneRel is a private API as far as I know, can you provide a testt case of examples of what you were actually trying to acheive?

Copy link
Contributor Author

@954-Ivory 954-Ivory Aug 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test case:

# admin.py
class MyPeriodicTaskInline(admin.StackedInline):
    model = MyPeriodicTask
    # ...
    # I want to render a `StackedInline` of `MyPeriodicTask` in `OtherModelAdmin` with my scene..
    # But it's not important.

class OtherModelAdmin(admin.ModelAdmin):
    model = OtherModel
    inlines = (
        MyPeriodicTaskInline,
    )
# models.py
class MyPeriodicTask(PeriodicTask):
    other_model = models.ForeignKey(
        'OtherModel',
        null=True,
        on_delete=models.CASCADE
    )

    def save(self, *args, **kwargs):
        self.kwargs = json.dumps('a_field_key',self.other_model.a_field)
        super().save(*args, **kwargs)
        # The bug is in it: 
        # This `save()` will call the `save_base()`.
        # But in `save_base()`, it will set `pre_save.sender = MyPeriodicTask`, not `PeriodicTask`.
        # So, the `PeriodicTask` can not receive signal with
        # [signals.pre_delete.connect(PeriodicTasks.changed, sender=PeriodicTask)](https://github.com/celery/django-celery-beat/blob/d4b97af62889527582194f3932e013ad972a88b3/django_celery_beat/models.py#L625)
        # [signals.pre_save.connect(PeriodicTasks.changed, sender=PeriodicTask)](https://github.com/celery/django-celery-beat/blob/d4b97af62889527582194f3932e013ad972a88b3/django_celery_beat/models.py#L625)
# query
my_periodic_task = MyPeriodicTask.first()
my_periodic_task.enabled = not my_periodic_task.enabled
my_periodic_task.save()
# the `PeriodicTasks.changed` will not be call.

Even without not overwrite save(), the pre_save.sender still be MyPeriodicTask.__class__.
Because in MyPeriodicTask, the self is MyPeriodicTask.
And Django use self.class to set sender.
delete() is the same, look this.

Copy link
Contributor Author

@954-Ivory 954-Ivory Aug 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have two way to fix it.

  1. Don't use signal, call PeriodicTasks.changed() in PeriodicTask.save() and PeriodicTask.delete().
  2. Like this PR, use reverse related to get all OneToOneField, then get thier __class__, connect to the signal.

Because OneToOneRel is a definite type for judge reverse related which is OnetoOneField, so I use it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i would prefer first approach

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you also add the tests as well

Copy link
Contributor Author

@954-Ivory 954-Ivory Oct 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you also add the tests as well

Yep, but I got the problem like this:
https://stackoverflow.com/questions/502916/django-how-to-create-a-model-dynamically-just-for-testing
I'm trying to solve it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is that related to this patch?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is that related to this patch?

Yep, I solved it.
Because I need to create the model in testing.

…eriodicTasks.save` and `PeriodicTasks.delete`
django_celery_beat/models.py Outdated Show resolved Hide resolved
@auvipy
Copy link
Member

auvipy commented Oct 13, 2022

looking for now-outdated files... none found
pickling environment... done
checking consistency... done

==============================
Undocumented Autodoc Modules

py

  • django_celery_beat.signals

@954-Ivory
Copy link
Contributor Author

looking for now-outdated files... none found pickling environment... done checking consistency... done

==============================

Undocumented Autodoc Modules

py

  • django_celery_beat.signals

I consolidated some files about Signals before (follow Django best practices).
Does it conflict about CI/CD?

@auvipy
Copy link
Member

auvipy commented Oct 13, 2022

the doc gen expects some documentation about the newly created module

@954-Ivory
Copy link
Contributor Author

the doc gen expects some documentation about the newly created module

Right, I will add the docs.

@auvipy
Copy link
Member

auvipy commented Oct 13, 2022

some minor Error: ERROR: flake8: commands failed
Error: ERROR: pydocstyle: commands failed need to be fixed

@954-Ivory
Copy link
Contributor Author

954-Ivory commented Oct 13, 2022

some minor Error: ERROR: flake8: commands failed Error: ERROR: pydocstyle: commands failed need to be fixed

It seems like some code specification problem.
I have tried to format them.
The migrations files is be generated, I didn't format it.
How to ignore code check of the migrations files?

@auvipy auvipy merged commit d65d0c6 into celery:master Oct 13, 2022
@auvipy
Copy link
Member

auvipy commented Oct 13, 2022

lets try this and report if anything goes wrong

@auvipy
Copy link
Member

auvipy commented Oct 13, 2022

can you help reviewing #563?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants