adamchainz / django-htmx

Extensions for using Django with htmx.
https://django-htmx.readthedocs.io/
MIT License
1.62k stars 140 forks source link

The middleware doesn't work properly in asgi mode #381

Closed CrazyUmka closed 11 months ago

CrazyUmka commented 12 months ago

Python Version

3.12.0

Django Version

4.2.6

Package Version

1.17.0

Description

When you turn on asgi mode in Django using daphne we get error message in middleware chain. This happens because Django uses the following function asgi.sync.markcoroutinefunction to mark whether a coroutine is present or not. In here https://github.com/adamchainz/django-htmx/blob/235499211b93920caecafbc208a85231f9f4e339/src/django_htmx/middleware.py#L33 instead of _is_coroutine there should be an attribute _is_coroutine_marker. To fix this, you can use the markcoroutinefunction or the MiddlewareMixin class to support backwards compatibility.

Example of configuration to reproduce behavior

INSTALLED_APPS = [
  "daphne",
  "django.contrib.admin",
  "django.contrib.auth",
  "django.contrib.contenttypes",
  "django.contrib.sessions",
  "django.contrib.messages",
  "django.contrib.staticfiles",
  "django_htmx",
]
MIDDLEWARE = [
  "django.middleware.security.SecurityMiddleware",
  "django.contrib.sessions.middleware.SessionMiddleware",
  "django.middleware.common.CommonMiddleware",
  "django.middleware.csrf.CsrfViewMiddleware",
  "django.contrib.auth.middleware.AuthenticationMiddleware",
  "django.contrib.messages.middleware.MessageMiddleware",
  "django.middleware.clickjacking.XFrameOptionsMiddleware",
  "django_htmx.middleware.HtmxMiddleware",
]

After that, you get next error: object HttpResponse can't be used in 'await' expression

adamchainz commented 12 months ago

Thank you for the report. I haven't been able to reproduce the problem because you didn’t provide enough details, but I have a proposed fix in #382. Please can you test it?

When you turn on asgi mode in Django using daphne we get error message in middleware chain.

Please provide the error message with the stack trace.

After that, you get next error: object HttpResponse can't be used in 'await' expression

Please provide the stack trace.

instead of _is_coroutine there should be an attribute _is_coroutine_marker. To fix this, you can use the markcoroutinefunction

I see this changed in Python 3.12. Thanks.

or the MiddlewareMixin class to support backwards compatibility.

The middleware deliberately doesn't use that class, which would make it slower because it uses sync_to_async.

Python Version

3.12.0

Django Version

4.2.6

Django 4.2.6 doesn’t currently support Python 3.12. The only supported versions are those listed in the release notes page: https://docs.djangoproject.com/en/4.2/releases/4.2/ . The tracking ticket: https://code.djangoproject.com/ticket/34118 . You will likely encounter other incompatibility issues, especially so early into Python 3.12's release cycle.

adamchainz commented 12 months ago

I also made an optimization PR on Django, following investigation into the changes to MiddlewareMixin: https://github.com/django/django/pull/17402 .