django отправить файл после завершения процесса - PullRequest
1 голос
/ 29 марта 2020

Я пытаюсь запустить функцию foo для загруженного файла, затем отправить выходной файл пользователю, я написал функции для сохранения загруженного файла и отправки электронных писем (оба работают), мне нужна помощь в прикреплении выходной файл после завершения функции foo(), который занимает около 1-2 часов. это мой views.py

import time
from django.shortcuts import render
from django.core.files.storage import FileSystemStorage
from django.core.mail import send_mail


def My_Upload(request):
    if request.method=="POST":
        uploaded_file = request.FILES['document']
        fs = FileSystemStorage()
        name = fs.save(name=uploaded_file.name,content=uploaded_file)
        context = {'Name':name}
        #function
        return render(request,'my_app/homepage.html',context=context)
    return render(request,'my_app/upload.html',)

def send_email_to(filename=None):
    foo(filename)
    send_mail("Your file is ready", "Here is your file", 'example@gmail.com', 
        ['1234@gmail.com'],fail_silently=False)

def foo(filename):
    #run some math on the file
    #creates a f'{filename}_done.csv'
    time.sleep(300)
    pass

есть ли способ сделать это, если нет, какие у меня есть альтернативы для достижения этой цели?

Ответы [ 2 ]

2 голосов
/ 30 марта 2020

Вот более полный ответ в папке вашего проекта, добавьте новый файл celery.py

from __future__ import absolute_import, unicode_literals
import os
from celery import Celery

os.environ.setdefault('DJANGO_SETTINGS_MODULE','Proj.settings')
app = Celery('Proj')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()
@app.task(bind=True)
def debug_task(self):
    print('Request: {0!r}'.format(self.request))

в Proj init.py

from __future__ import absolute_import, unicode_literals

# This will make sure the app is always imported when
# Django starts so that shared_task will use this app.
from .celery import app as celery_app

__all__ = ('celery_app',)

Это просто настройка по умолчанию для любое приложение сельдерея, для вашего случая в вашем приложении создайте новый файл tasks.py

from celery import shared_task
import time
from django.core.mail import send_mail
@shared_task
def sent_email_to():
    time.sleep(10)
    send_mail("Your file is ready", "Here is your file", '123@gmail.com', 
        ['example@gmail.com'],fail_silently=False)
return None

, затем в вашем views.py

from .tasks import sent_email_to

def My_Upload(request):
    if request.method=="POST":
        uploaded_file = request.FILES['document']
        fs = FileSystemStorage()
        name = fs.save(name=uploaded_file.name,content=uploaded_file)
        context = {'Name':name}
        sent_email_to()
        return render(request,'my_app/homepage.html',context=context)
    return render(request,'my_app/upload.html',)

и наконец в settings.py вам нужно добавить

CELERY_BROKER_URL = 'CELERY_SERVER_URL'
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'

запустить сервер сельдерея, используя

celery -A Proj -l info
0 голосов
/ 29 марта 2020

Поскольку это занимает слишком много времени, вы сказали, что 1-2 часа, вы можете сделать сумку с сумкой , используя сельдерей и вызвать send_email_to в самой задаче. Для прикрепления файла вы можете посмотреть EmailMessage

Здесь вы можете сослаться Сельдерей , добавить вызов send_mail_to как задержка (запуск в baground ) в функции My_Upload.

Это должно выглядеть примерно так:

import time
from django.shortcuts import render
from django.core.files.storage import FileSystemStorage
from django.core.mail import send_mail
from proj.celery import app

def My_Upload(request):
    if request.method=="POST":
        uploaded_file = request.FILES['document']
        fs = FileSystemStorage()
        name = fs.save(name=uploaded_file.name,content=uploaded_file)
        context = {'Name':name}
        send_mail_to.delay()
        return render(request,'my_app/homepage.html',context=context)
    return render(request,'my_app/upload.html',)

@app.task
def send_email_to(filename=None):
    foo(filename)
    send_mail("Your file is ready", "Here is your file", 'example@gmail.com', 
        ['1234@gmail.com'],fail_silently=False)

def foo(filename):
    #run some math on the file
    #creates a f'{filename}_done.csv'
    time.sleep(300)
    pass

PS: proj - это ваше django -проектное имя

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...