Skip to main content

Display a fallback in templates until its children have finished loading.

Project description

Django Suspense

PyPI version PyPI Supported Python Versions PyPI Supported Django Versions Coverage)

Django Suspense is small package to easily display a fallback in templates until children have finished loading.

Quick start

1. Install package:

To get started, install the package from pypi:

pip install django-suspense

Now you can add suspense to your django project. Change your INSTALLED_APPS setting like this:

INSTALLED_APPS = [
    ...,
    "suspense",
]

Optionally, you can specify suspense as builtins and this will be available in any of your templates without additionally specifying {% load suspense %}:

TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [BASE_DIR / "templates"],
        "APP_DIRS": True,
        "OPTIONS": {
            "context_processors": [
                # ... list of default processors
            ],
            "builtins": ["suspense.templatetags.suspense"], # <--
        },
    },
]

If you choose not use it as a built-in, you will need to add {% load suspense %} to the top of your template whenever you want to use suspense.

2. Create view with slow lazy load object:

Because django executes database queries lazily, they may sometimes not work as expected. Let's try to create a very slow but lazy object and write a view function:

from suspense.shortcuts import render

# app/views.py
def view(request):
    def obj():
        import time

        time.sleep(1)
        return range(10)

    return render(request, 'template.html', {'obj': obj})

3. Use suspense in your template:

Let's now add the output of the received data to the template. At this point, we still haven't made a database query, so we can easily and quickly show the template right away.

{% load suspense %}

<ul>
    {% suspense %}
        {% fallback %}
            <li class="skeleton">Loading ... </li>
        {% endfallback %}

        {% for data in obj %}
            <li>{{ data }}</li>
        {% endfor %}
    {% endsuspense %}
</ul>

Once obj is ready for use, we will show it. But until it is ready, fallback works. While we are waiting for the data to be displayed, a request is made on the client side.

Suspense does not add additional DOM elements after rendering the final result. That's why syntactically the code above will be valid.

4. Hooray! Everything is ready to use it.

Troubleshooting

Safari delay in rendering

On Safari if your webpage is very light/simple, you may experience a delay in rendering.

Ex: the page renders only after some django-suspense or all content is downloaded.

WebKit has an issue with streaming responses requiring a certain amount of visible content before to actually start rendering.

See webkit issue #252413

If you are experiencing this issue, you can use the additional {% webkit_extra_invisible_bytes %} template tag to add a few extra invisible bytes in Safari.

{% load suspense %}

{% webkit_extra_invisible_bytes %}

By default the webkit_extra_invisible_bytes adds 200 bytes but you can specify a different amount:

{% webkit_extra_invisible_bytes 300 %}

Content Security Policy (CSP) nonce error because of strict-dynamic

If you are using a Content Security Policy (CSP) with nonce and strict-dynamic, you may need to add the nonce attribute to the script tag.

You can override the suspense/replacer.html template and add the nonce attribute to the script tag.

With django-csp:

{% extends "suspense/replacer.html" %}

{% block script_attributes %}nonce="{{request.csp_nonce}}"{% endblock %}

Contributing

If you would like to suggest a new feature, you can create an issue on the GitHub repository for this project. Also you can fork the repository and submit a pull request with your changes.

License

This project is licensed under the MIT License. See the LICENSE file for more information.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_suspense-1.1.0.tar.gz (9.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_suspense-1.1.0-py3-none-any.whl (8.1 kB view details)

Uploaded Python 3

File details

Details for the file django_suspense-1.1.0.tar.gz.

File metadata

  • Download URL: django_suspense-1.1.0.tar.gz
  • Upload date:
  • Size: 9.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.12.7

File hashes

Hashes for django_suspense-1.1.0.tar.gz
Algorithm Hash digest
SHA256 1f6b05ec4767ea830b13a62e9b1c1dedfb3c752f90ce249ebd0ba741aca42f80
MD5 21afcdb10730ed98aba8719e3d0eac3d
BLAKE2b-256 00c711c0970c2883caf9870965f373b1e487bb617f53403a9bbe8544681b08cb

See more details on using hashes here.

File details

Details for the file django_suspense-1.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for django_suspense-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fc4e43b5a35ae54db0420a3913340797aeab5060df923ec3ee9fafe95c7959ab
MD5 d5dfd1d0e7788512b4e75335faa2fd73
BLAKE2b-256 d768af4d5e760c8898a2212a11012f73da38cae606abc7482284626144d1161e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page