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": [
                "django.template.context_processors.debug",
                "django.template.context_processors.request",
                "django.contrib.auth.context_processors.auth",
                "django.contrib.messages.context_processors.messages",
            ],
            "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. Add suspense to urls.py:

This is necessary because some parts of the pages will be loaded asynchronously (via http).

from django.urls import include, path


urlpatterns = [
    ...,
    path('/_suspense/', include('suspense.urls'))
]

3. 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:

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

        i = 0
        while i < 10:
            yield i
            i += 1
            time.sleep(1)

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

4. 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 %}

<div class="list">
    {% suspense %}
        {% fallback %}
            <div class="skeleton">Loading ... </div>
        {% endfallback %}

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

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.

5. Hooray! Everything is ready to use it.

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.0.2.tar.gz (7.9 kB view hashes)

Uploaded Source

Built Distribution

django_suspense-1.0.2-py3-none-any.whl (6.2 kB view hashes)

Uploaded Python 3

Supported by

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