celery / django-celery-beat

Celery Periodic Tasks backed by the Django ORM
Other
1.71k stars 428 forks source link

I think there is no longer a need for `self.celery_app.loader.import_default_modules()` in the admin #714

Open gotounix opened 10 months ago

gotounix commented 10 months ago

I removed _modules in TaskSelectWidget, everything works fine.

Is it still necessary to use self.celery_app.loader.import_default_modules()?

auvipy commented 10 months ago

I would love to know more detail

gotounix commented 10 months ago

I would love to know more detail

When I try to access TaskSelectWidget().choices elsewhere, self.celery_app.loader.import_default_modules() causes a circular import error in the project's urls.py.

Nigel2392 commented 10 months ago

I would love to know more detail

When I try to access TaskSelectWidget().choices elsewhere, self.celery_app.loader.import_default_modules() causes a circular import error in the project's urls.py.

You likely have a circular import then... Share the traceback?

gotounix commented 9 months ago
from rest_framework import serializers
from django_celery_beat.models import PeriodicTask
from django_celery_beat.admin import TaskSelectWidget

class PeriodicTaskSerializer(serializers.ModelSerializer):
    task = serializers.ChoiceField(choices=TaskSelectWidget().choices[1:])  # this will raise circular import 
    class Meta:
        model = PeriodicTask
        fields = '__all__'

Traceback:

Exception in thread django-main-thread:
Traceback (most recent call last):
  File "E:\Test\test-django-celery-beat-issue-714\venv\lib\site-packages\django\urls\resolvers.py", line 717, in url_patterns
    iter(patterns)
TypeError: 'module' object is not iterable

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Program Files\Python310\lib\threading.py", line 1016, in _bootstrap_inner
    self.run()
  File "C:\Program Files\Python310\lib\threading.py", line 953, in run
    self._target(*self._args, **self._kwargs)
  File "E:\Test\test-django-celery-beat-issue-714\venv\lib\site-packages\django\utils\autoreload.py", line 64, in wrapper
    fn(*args, **kwargs)
  File "E:\Test\test-django-celery-beat-issue-714\venv\lib\site-packages\django\core\management\commands\runserver.py", line 133, in inner_run
    self.check(display_num_errors=True)
  File "E:\Test\test-django-celery-beat-issue-714\venv\lib\site-packages\django\core\management\base.py", line 485, in check
    all_issues = checks.run_checks(
  File "E:\Test\test-django-celery-beat-issue-714\venv\lib\site-packages\django\core\checks\registry.py", line 88, in run_checks
    new_errors = check(app_configs=app_configs, databases=databases)
  File "E:\Test\test-django-celery-beat-issue-714\venv\lib\site-packages\django\core\checks\urls.py", line 14, in check_url_config
    return check_resolver(resolver)
  File "E:\Test\test-django-celery-beat-issue-714\venv\lib\site-packages\django\core\checks\urls.py", line 24, in check_resolver
    return check_method()
  File "E:\Test\test-django-celery-beat-issue-714\venv\lib\site-packages\django\urls\resolvers.py", line 494, in check
    for pattern in self.url_patterns:
  File "E:\Test\test-django-celery-beat-issue-714\venv\lib\site-packages\django\utils\functional.py", line 57, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "E:\Test\test-django-celery-beat-issue-714\venv\lib\site-packages\django\urls\resolvers.py", line 715, in url_patterns
    patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
  File "E:\Test\test-django-celery-beat-issue-714\venv\lib\site-packages\django\utils\functional.py", line 57, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "E:\Test\test-django-celery-beat-issue-714\venv\lib\site-packages\django\urls\resolvers.py", line 708, in urlconf_module
    return import_module(self.urlconf_name)
  File "C:\Program Files\Python310\lib\importlib\__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 883, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "E:\Test\test-django-celery-beat-issue-714\mysite\urls.py", line 22, in <module>
    path("polls/", include("polls.urls")),
  File "E:\Test\test-django-celery-beat-issue-714\venv\lib\site-packages\django\urls\conf.py", line 38, in include
    urlconf_module = import_module(urlconf_module)
  File "C:\Program Files\Python310\lib\importlib\__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 883, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "E:\Test\test-django-celery-beat-issue-714\polls\urls.py", line 3, in <module>
    from . import views
  File "E:\Test\test-django-celery-beat-issue-714\polls\views.py", line 23, in <module>
    from .serializers import PeriodicTaskSerializer
  File "E:\Test\test-django-celery-beat-issue-714\polls\serializers.py", line 7, in <module>
    class PeriodicTaskSerializer(serializers.ModelSerializer):
  File "E:\Test\test-django-celery-beat-issue-714\polls\serializers.py", line 8, in PeriodicTaskSerializer
    print(TaskSelectWidget().choices[1:])
  File "E:\Test\test-django-celery-beat-issue-714\venv\lib\site-packages\django_celery_beat\admin.py", line 33, in choices
    self._choices = self.tasks_as_choices()
  File "E:\Test\test-django-celery-beat-issue-714\venv\lib\site-packages\django_celery_beat\admin.py", line 25, in tasks_as_choices
    _ = self._modules
  File "E:\Test\test-django-celery-beat-issue-714\venv\lib\site-packages\kombu\utils\objects.py", line 40, in __get__
    return super().__get__(instance, owner)
  File "C:\Program Files\Python310\lib\functools.py", line 981, in __get__
    val = self.func(instance)
  File "E:\Test\test-django-celery-beat-issue-714\venv\lib\site-packages\django_celery_beat\admin.py", line 44, in _modules
    self.celery_app.loader.import_default_modules()
  File "E:\Test\test-django-celery-beat-issue-714\venv\lib\site-packages\celery\loaders\base.py", line 104, in import_default_modules
    raise response
  File "E:\Test\test-django-celery-beat-issue-714\venv\lib\site-packages\celery\utils\dispatch\signal.py", line 276, in send
    response = receiver(signal=self, sender=sender, **named)
  File "E:\Test\test-django-celery-beat-issue-714\venv\lib\site-packages\celery\fixups\django.py", line 97, in on_import_modules
    self.worker_fixup.validate_models()
  File "E:\Test\test-django-celery-beat-issue-714\venv\lib\site-packages\celery\fixups\django.py", line 137, in validate_models
    run_checks()
  File "E:\Test\test-django-celery-beat-issue-714\venv\lib\site-packages\django\core\checks\registry.py", line 88, in run_checks
    new_errors = check(app_configs=app_configs, databases=databases)
  File "E:\Test\test-django-celery-beat-issue-714\venv\lib\site-packages\django\core\checks\urls.py", line 14, in check_url_config
    return check_resolver(resolver)
  File "E:\Test\test-django-celery-beat-issue-714\venv\lib\site-packages\django\core\checks\urls.py", line 24, in check_resolver
    return check_method()
  File "E:\Test\test-django-celery-beat-issue-714\venv\lib\site-packages\django\urls\resolvers.py", line 494, in check
    for pattern in self.url_patterns:
  File "E:\Test\test-django-celery-beat-issue-714\venv\lib\site-packages\django\utils\functional.py", line 57, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "E:\Test\test-django-celery-beat-issue-714\venv\lib\site-packages\django\urls\resolvers.py", line 725, in url_patterns
    raise ImproperlyConfigured(msg.format(name=self.urlconf_name)) from e
django.core.exceptions.ImproperlyConfigured: The included URLconf 'mysite.urls' does not appear to have any patterns in it. If you see the 'urlpatterns' variable with valid patterns in the file then the issue is probably caused by a circular import.

I found remove _modules in TaskSelectWidget, everything works fine.

@auvipy @Nigel2392

auvipy commented 9 months ago

Thanks for the report. I have to check it properly

gotounix commented 4 months ago

Thanks for the report. I have to check it properly

Do you check it ? @auvipy

auvipy commented 4 months ago

It would be easier to review a PR on this front