[PYTHON] Dans Django, affichez les résultats des lots (commandes) de manière séquentielle en HTML

(On a l'impression que output_buffering est désactivé en PHP)

Utilisez StreamingHttpResponse.

Étant donné que le premier argument de StreamingHttpResponse est un générateur, écrivez le lot avec le générateur.

Dans cet exemple, la commande shell est utilisée comme générateur.

import subprocess

from django.http import StreamingHttpResponse
from django.utils.encoding import smart_str
from django.utils.html import escape
from django.views import View


def run_process_as_generator(*args, **kwargs):
    """
Renvoyer le résultat du sous-processus dans le générateur
    :rtype: generator
    """
    kwargs.setdefault('stdout', subprocess.PIPE)
    kwargs.setdefault('stderr', subprocess.STDOUT)

    popen = subprocess.Popen(*args, **kwargs)

    while True:
        line = popen.stdout.readline()
        if line:
            yield line

        if not line and popen.poll() is not None:
            break


def linebreaksbr(gen):
    """
Sur chaque ligne du générateur<br />Mettez
Intelligent au cas où_str
    :type gen: generator
    :rtype: generator
    """
    for line in gen:
        yield '{}<br />\n'.format(escape(smart_str(line)))


def task():
    """
Exécuter le lot
    :rtype: generator
    """
    return linebreaksbr(
        run_process_as_generator(
            "for i in {1..10}; do sleep 1s; echo ${i}; done",
            shell=True
        ))


class SlowCommandView(View):
    """
    task()Une vue qui renvoie le résultat de
    """
    def get(self, request, *args, **kwargs):
        response = StreamingHttpResponse(
            task(),
            content_type="text/html; charset=utf-8")

        return response

Si vous écrivez un lot en Python, c'est une bonne idée d'utiliser le rendement au lieu d'imprimer un journal à l'impression.

def task():
    yield 'start'
    ...
    yield 'phase-1'
    ...
    for xx in xxx:
         yield xx
    yield 'end'

référence: Obtenir une sortie standard en temps réel avec Python subprocess-Qiita

Request and response objects | Django documentation | Django

Recommended Posts

Dans Django, affichez les résultats des lots (commandes) de manière séquentielle en HTML
Afficher le HTML dans le notebook Jupyter
Django ~ Affichons-le sur le navigateur ~
Recevoir et afficher les données de formulaire HTML en Python
Afficher un message d'erreur lorsque la connexion échoue dans Django
Modèle HTML Django partie 2
Modèle dans Django
Modèle HTML Django
Commande Django + Docker
Formulaire à Django