es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Subiendo videos en Django Rest Framework

He creado una API de publicaciones que permitirá subir imágenes y videos para blogs. Puedo manejar varias imágenes sin problemas. Pero también tengo que enviar un video desde el frontend. He utilizado Filefield para el video. No soy experto en APIs, pero creo que, dado que el código que he escrito es síncrono, todo lo que he escrito se hará al mismo tiempo. Ahora, el problema es que si un usuario quiere subir un video muy grande, por ejemplo, de 200-500 mb, la respuesta de la llamada a la API de publicación será muy larga. ¿Hay alguna manera de guardar primero la publicación del blog, devolver la respuesta y luego comenzar a subir el video en la base de datos del servidor en vivo?

Mis modelos:

class Blogposts(models.Model):

blog_title = models.CharField(max_length=100, blank=True)

video = models.FileField(upload_to="media", null=True)

He intentado usar las señales de Django, pero también son síncronas. Todo lo que he mencionado anteriormente también podría estar equivocado, no estoy seguro. ¿Pero cómo abordar esto? ¿O debería usar Django Celery?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Como has mencionado, el uso de código síncrono para subir archivos grandes puede resultar en tiempos de respuesta largos, lo cual puede ser una mala experiencia para el usuario.

    Para abordar este problema, una posible solución es utilizar Django Celery, que es una cola de tareas que te permite ejecutar tareas en segundo plano.

    Aquí te muestro cómo podrías implementarlo en tu caso:

    1. Instala Django Celery: pip install celery
    2. Configura Celery en tu proyecto Django. Aquí tienes un ejemplo de configuración:

    # settings.py
    
    # Configuración de Celery
    CELERY_BROKER_URL = 'redis://localhost:6379/0'
    CELERY_RESULT_BACKEND = 'redis://localhost:6379/0'
    CELERY_ACCEPT_CONTENT = ['application/json']
    CELERY_TASK_SERIALIZER = 'json'
    CELERY_RESULT_SERIALIZER = 'json'
    

    Esta configuración asume que tienes Redis funcionando en localhost.

    1. Crea una tarea de Celery para subir videos. Aquí tienes un ejemplo:
    # tasks.py
    
    from celery import shared_task
    
    
    @shared_task
    def upload_video(blogpost_id, video_path):
        blogpost = Blogposts.objects.get(pk=blogpost_id)
        blogpost.video.save(video_path.name, video_path)
    

    Esta tarea toma blogpost_id y video_path como argumentos, y guarda el video en la publicación de blog correspondiente.

    1. Modifica tu vista de API para utilizar Celery. Aquí tienes un ejemplo:
    # views.py
    
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from rest_framework.decorators import parser_classes
    from rest_framework.parsers import MultiPartParser
    from .tasks import upload_video
    
    
    class BlogpostView(APIView):
    
        parser_classes = [MultiPartParser]
    
        def post(self, request, format=None):
            blogpost_data = request.data.copy()
            video_file = blogpost_data.pop('video', None)
    
            # Guardar la publicación del blog
            blogpost_serializer = BlogpostSerializer(data=blogpost_data)
            if blogpost_serializer.is_valid():
                blogpost = blogpost_serializer.save()
    
                # Iniciar la tarea de subida de video
                if video_file:
                    upload_video.delay(blogpost.id, video_file)
    
                return Response(blogpost_serializer.data, status=201)
    
            return Response(blogpost_serializer.errors, status=400)
    

    Esta vista utiliza MultiPartParser para manejar las subidas de archivos y guarda la publicación del blog utilizando un serializador. Si hay un archivo de video presente en la solicitud, inicia la tarea upload_video utilizando delay() en lugar de llamarla directamente. Esto encolará la tarea en el trabajador de Celery y devolverá una respuesta al cliente de inmediato.

    Al utilizar Celery, puedes delegar el trabajo pesado de subir archivos a un proceso en segundo plano, lo cual debería resultar en una mejor experiencia de usuario.

Comments are closed.