Create spreadsheets with Django

Asked

Viewed 179 times

0

Hello, I am implementing a button to turn a Query into a spreadsheet and make this download available. For this I created a View to generate Excel, follows:

def export_view_csv(request):
    if request == 'POST':
        dados = request.POST.get('csv_sender')
        response = HttpResponse(content_type='text/csv')
        response['Content-Disposition'] = 'attachment; filename=Consulta' + str(datetime.now()) + '.csv'

        writer = csv.writer(response)
        writer.writerow(['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'])

        for info in dados:
            writer.writerow(
                [info['nomefa'], info['razaos'], info['cnpj'], info['uf'], info['situac'], info['porte'], info['lograd'],
                 info['numero'],
                 info['comple'], info['muibge'], info['dsituc'], info['capsoc']])

    return response

and created the form by sending to this view the hidden field, follows Forms:

<form method="POST" action = "{% url 'core:csv-export' %}">
      <div class="module-option clearfix">
           <div class="input-append pull-left">
                <input type="hidden" name="csv_sender" value="{{ results }}"/>
                {% csrf_token %}
                 <button type="submit" class="btn" name="submit">
                         <a>Baixar Planilha</a>
                 </button>
           </div>
      </div>
</form>

But I’m facing the following mistake and I don’t know how to proceed:

AttributeError at /csv-export/
'str' object has no attribute 'get'

py.

app_name = 'core'

urlpatterns = [
    path('', IndexView.as_view(), name='index'),

    path('mylogout/', LogoutView.as_view(), name='mylogout'),
    path('register/', RegisterView.as_view(), name='register'),
    path('contato/', contato_email, name='contato'),
    path('csv-export/', export_view_csv, name='csv-export'),
]

If anyone can give me a light...

  • Puts the urls.py in your post as well.

  • Of course, placed!

  • Sorry to ask in homeopathic doses, you can put the view that calls the form?

  • It is the first code of the post as I understood your question

  • So, you have no other view related to this process of generating and downloading?

  • The variable request is coming to your view as a string and not as the object containing the HTTP request coming from the browser (so much so that the validation request == "POST" is working because it should be request.method == "POST").

  • Thanks Giovanni, this was exactly my problem. I managed to solve thanks for the help

Show 2 more comments

1 answer

0


I believe it would be easier to work with more than one view, using MEDIA_URL to save a temporary file.

The stream would be to access the view that generates the data and this redirect to the view that would allow the download.

Views

First view - access_data

def buscar_dados(param1, param2...):
    # busca os dados
    # salva os dados
    # algo como: ???.save(os.path.join(settings.MEDIA_ROOT, file_name))
    return file_name  # inclui o /path/to/file/arquivo.xlsx


def acessa_dados(request):
    if request.method == 'POST':
        form = MyQueryForm(request.POST)
        if form.is_valid():
            resultado = busca_dados(passar parametros aqui>)
            return HttpResponseRedirect(reverse('minha_app:get_file', args=[resultado]))
    else:
        form = MyQueryForm()
    return render(request, 'acessa_dados_form.html', {'form': form})

Second view - get_file

def get_file(request, file_path):
    return render(request, 'get_file.html', context={'file_path': f'/media/{file_path}'})


def download(request, file_path):
    if os.path.exists(file_path):
        with open(file_path, 'rb') as fh:
            response = HttpResponse(fh.read(), content_type="application/vnd.ms-excel")
            response['Content-Disposition'] = 'inline; filename=' + os.path.basename(file_path)
            return response
    raise Http404

Url.py

app_name = 'minha_app'

urlpatterns = [
    path('', acessa_dados, name='acessa'),
    path('get_file/<str:file_path>', get_file, name='get_file'),
    path('download/<str:file_path>', download, name='download'),
] + static(settings.MEDIA_URL,  document_root=settings.MEDIA_ROOT)

In time: get_file.html is just a file download link.

I hope I’ve helped

Browser other questions tagged

You are not signed in. Login or sign up in order to post.