Django从用户那里获取数据,离线处理以向用户发送CSV

时间:2018-05-21 11:30:29

标签: django django-views

我可能无法向您提供有关我尝试的代码的任何信息。但搜索或研究都没有给我带来有效的结果。

我想做什么? 我有一个用户提交CSV文件的表单。在后端处理此文件以从DB检索数据。从DB恢复的数据再次以CSV格式写入并邮寄给用户。

此处理大约需要5-10分钟。因此,我想向用户显示一条消息:您的工作正在处理中,一旦完成,您将获得CSV文件。

截至目前我的代码。

def bulkserachpro(request):
    with request.FILES['searchnum'] as csvfile:
                spamreader = csv.reader(csvfile,dialect=excel)
                next(spamreader)
                a = [] 
                b = []
                for row in spamreader:
                    a.append((row[0]).upper())
                data_list = nummodel.objects.filter(number__in=a)
                csvfile = StringIO.StringIO()
                csvwriter = csv.writer(csvfile)
                csvwriter.writerow(['a','b'])
                for data in data_list:
                    csvwriter.writerow([data.a,data.b])
                message = EmailMessage("Hello","Your report","email@gmail.com",["emailto@gmail.com"])
                message.attach('invoice.csv', csvfile.getvalue(), 'text/csv')
                message.send()
            return render(request,'bulkpro.html',messages.add_message(request, messages.SUCCESS,'File uploaded Succesfully.'))

此代码完成其工作。但由于用户不能等待5-10分钟,他将收到超时错误消息。 我应该在这里更改以便用户获得关注消息,并且一旦处理完成,他就会收到带附件的电子邮件。

  

您的文件已收到,将被处理并发送到您的邮件ID。

2 个答案:

答案 0 :(得分:1)

尽管Celery通常用于此类事情,但对于这种简单的情况,您可能只是在一个线程中运行csv处理。

例如,创建一个封装处理代码的线程:

import threading

class ProcessCsv(threading.Thread):

    def __init__(self, csvfile):
        self.csvfile = csvfile
        self.daemon = True

    def run(self):
        spamreader = csv.reader(self.csvfile,dialect=excel)
        next(spamreader)
        a = [] 
        b = []
        for row in spamreader:
            a.append((row[0]).upper())
        data_list = nummodel.objects.filter(number__in=a)
        csvfile = StringIO.StringIO()
        csvwriter = csv.writer(csvfile)
        csvwriter.writerow(['a','b'])
        for data in data_list:
            csvwriter.writerow([data.a,data.b])
        message = EmailMessage("Hello","Your report","email@gmail.com",["emailto@gmail.com"])
        message.attach('invoice.csv', csvfile.getvalue(), 'text/csv')
        message.send()

然后你的视图可以启动线程,只显示"你的文件被收到,它将被处理......"消息:

def bulkserachpro(request):
    process = ProcessCsv(request.FILES['searchnum'])
    process.start()  # Start the csv processing in a separate thread
    # Display "your file is being processed" message
    return render(request,'bulkpro.html',messages.add_message(request, messages.SUCCESS,'File uploaded Succesfully.'))

答案 1 :(得分:0)

在视图中等待肯定会超时,任何解决问题的技巧都不是直截了当的。而是定期进行AJAX调用以了解下面的状态。

  • 发布CSV后,启动一个完成工作的芹菜任务。

  • AJAX查询任务的状态(在上次调用中传递的task-id)以了解作业的状态。

  • 相应地显示任务的完成或进度。

  • 在芹菜任务中发送包含CSV的电子邮件。