Django upload excel file, process with pandas, download as csv - python

I'm running Django on a localhost (Later to run on a LAN) where the idea is I can go onto the webpage, click a button where you're prompted to select an excel file from your computer. Pandas will do work on said excel file and Django/Pandas will make excel file of this Pandas data frame as a download prompt.
I've got Django running and using the code below from the module 'Django-Excel' does the basics of what I want. Excel file in ---> excel file out, no saving the file to a database or anything just keeping it in the memory. However, I cannot find a way to shoehorn Pandas into it. The main problem I have is I'm unsure how to return an excel file using Pandas. I've been using '.to_excel()' in my offline python code, however, haven't found a way to use it in a localhost running Django. I'm sure I'm missing something really simple but I just can't get it.
Maybe if someone could show a simple example of say, uploading an excel, pandas will multiply a column of numbers in the excel by 2, new excel is outputted to read/save.
from django.shortcuts import render, redirect
from django.http import HttpResponseBadRequest, HttpResponse
from _compact import JsonResponse
from django import forms
import django_excel as excel
from polls.models import Question, Choice
class UploadFileForm(forms.Form):
file = forms.FileField()
# Create your views here.
def upload(request):
if request.method == "POST":
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
filehandle = request.FILES['file']
# do pandas here to filehandle/ put filehandle into a function
return excel.make_response(filehandle.get_sheet(), "csv",
file_name="download")
else:
form = UploadFileForm()
return render(
request,
'upload_form.html',
{
'form': form,
'title': 'Excel file upload and download example',
'header': ('Please choose any excel file ' +
'from your cloned repository:')
})
Thank you very much, sorry if this isn't clear It's my first time posting on this website, if you don't understand what I'm asking for I'll elaborate more.

I'll upload my answer for anyone looking at this in the future :-)
def uploads(request):
if request.method == "POST":
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
kappa = request.FILES['file']
# Do work on kappa/excel file here with Pandas
output = io.BytesIO()
writer = pd.ExcelWriter(output, engine='xlsxwriter')
kappa.to_excel(writer, index=False)
writer.save()
output.seek(0)
response = HttpResponse(output,
content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
response['Content-Disposition'] = 'attachment; filename=%s.xlsx' % 'Download'
return response
else:
form = UploadFileForm()
return render(request, 'upload_form.html', {'form': form})
I abandoned using 'Django-excel' and instead used 'BytesIO' from the io module. This has the bonus of not relying on a third-party module.
you're able to write a Pandas dataframe to io.BytesIO() and then use that in your HttpResponse.

Related

Saving django form as excel file with saving to db also in Django

I have code like this. It's working example of saving data specified in forms.py, and some data taken from current logged user.
#login_required
def save(request):
if request.method == 'POST':
form = ExcelForm(data=request.POST)
if form.is_valid():
name = request.user.first_name
lastname = request.user.last_name
date = datetime.datetime.now().date()
valid_form = form.save(commit=False)
valid_form.firstName = name
valid_form.lastName = lastname
valid_form.date = date
valid_form.save()
return redirect('account:panel')
else:
form = ExcelForm(data=request.POST)
return render(request, 'account/panel.html', {'form': form})
This form is saved to sqllite db. My main goal is to save this form as excel file. How can I deal with this problem ? How to pass data to the sheet and with clicking submit button in my html file saving to excel file and to database in the same time ? thanks for all answers in the future.
Rather than storing the data in excel, you can create a new view to export the data as excel format. You can try like this using django-import-export. Example of writing a view:
from django.http import HttpResponse
from .resources import PersonResource
def export(request):
person_resource = PersonResource()
dataset = person_resource.export()
response = HttpResponse(dataset.xls, content_type='application/vnd.ms-excel')
response['Content-Disposition'] = 'attachment; filename="persons.xls"'
return response
You can check this medium post as well for exporting data using view.

python django run bash script in server

I would like to create a website-app to run a bash script located in a server. Basically I want this website for:
Upload a file
select some parameters
Run a bash script taking the input file and the parameters
Download the results
I know you can do this with php, javascript... but I have never program in these languages. However I can program in python. I have used pyQT library in python for similar purposes.
Can this be done with django? or should I start learning php & javascript?
I cannot find any tutorial for this specific task in Django.
This can be done in Python using the Django framework.
First create a form including a FileField and the fields for the other parameters:
from django import forms
class UploadFileForm(forms.Form):
my_parameter = forms.CharField(max_length=50)
file = forms.FileField()
Include the UploadFileForm in your view and call your function for handling the uploaded file:
from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import UploadFileForm
# Imaginary function to handle an uploaded file.
from somewhere import handle_uploaded_file
def upload_file(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
my_parameter = form.cleaned_data['my_parameter']
# Handle the uploaded file
results = handle_uploaded_file(request.FILES['file'], title)
# Clear the form and parse the results
form = UploadFileForm()
return render(request, 'upload.html', {'form': form, 'results': results})
else:
form = UploadFileForm()
return render(request, 'upload.html', {'form': form})
Create the function to handle the uploaded file and call your bash script:
import subprocess
import os
def handle_uploaded_file(f, my_parameter):
file_path = os.path.join('/path/to/destination/', f.name)
# Save the file
with open(file_path, 'wb+') as destination:
for chunk in f.chunks():
destination.write(chunk)
# Call your bash script with the
output = subprocess.check_output(['./my_script.sh',str(file_path),str(my_parameter)], shell=True)
return output
Check out https://docs.djangoproject.com/en/1.10/topics/http/file-uploads/ for more examples and instructions on how the handle file uploads in Django.

Django - how to import from a .csv file in memory

I'm writing a page to upload a .csv file and import its content into my models. My current view:
class ContentImport(LoginRequiredMixin, PermissionRequiredMixin,View):
permission_required = 'delivery.change_delivery'
def get(self, request, *args, **kwargs):
form = UploadFileForm()
return render(request, 'delivery/content_import.html', { 'form': form })
def import_contents(self, f):
reader = csv.reader(f)
for row in reader:
print row[0]
def post(self, request, *args, **kwargs):
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
self.import_contents(request.FILES['file'].read())
messages.add_message(self.request, messages.SUCCESS, "Contents deleted successfully.")
return redirect(reverse('delivery:delivery-detail', args=[self.kwargs['delivery_id']]))
else:
messages.add_message(self.request, messages.ERROR, "Select a file to upload.")
return redirect(reverse('delivery:delivery-content-import', args=[self.kwargs['delivery_id']]))
My question is about the import_contents method and the call for it self.import_contents(request.FILES['file'].read()). When I print row[0] I get the following error: list index out of range.
My idea with this view is to upload a file, not saving it in the server, read the .csv from the memory and create new records in my models. This read from .csv I got from other answers here in stackoverflow.
I think the problem is how I pass the file to the import_contents function or how I read from it. I just can't figure out. Can you help me? If you have a suggestion on how to do it in an easier way, or the right way, let me know.
Thanks for any help
This is your problem.
self.import_contents(request.FILES['file'].read())
csv.reader() expects a file like object, not its content.
This can definitely be construed as a related answer.

How can i perform validation on uploaded file in django

I am uploading the pdf file in django form.
But i need to perform the validation on the pdf file by reading the contents of file and then checking and if its not valid then give some error message.
But i am not able to find how can i get the pdf file location so that i can read the file and do some test.
I don't want to first save in temp location and then do validation and then delete the file
all i need is the path of the file so that i can run some system command on the file
The example below is based on the Basic file uploads example in the django docs. You can have a function in this example called check_pdf that does your validation on the pdf file and returns true/false based on whether it is valid. Depending on that you redirect the user to a success or invalid pdf page. This is the simplest way of doing it. You could do more and present specific error messages using the forms apis.
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
def upload_file(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
if check_pdf(request.FILES['file'].name):
return HttpResponseRedirect('/success/url/')
else:
return HttpResponseRedirect('/invalid_pdf/url/')
else:
form = UploadFileForm()
return render_to_response('upload.html', {'form': form})

import csv file into mysql database using django web application

i try to upload a csv file into my web application and store it into mysql database but failed.Please can anyone help me?
my user.py script:
def import_contact(request):
if request.method == 'POST':
form = UploadContactForm(request.POST, request.FILES)
if form.is_valid():
csvfile = request.FILES['file']
print csvfile
csvfile.read()
testReader = csv.reader(csvfile,delimiter=' ', quotechar='|')
for row in testReader:
print "|".join(row)
return HttpResponseRedirect('/admin')
else:
form = UploadContactForm()
vars = RequestContext(request, { 'form': form })
return render_to_response('admin/import_contact.html', vars)
my forms.py script:
class UploadContactForm(forms.Form):
file = forms.FileField(label='File:', error_messages = {'required': 'File required'})
Since you haven't provided the code for the getcsv function, I'll have to use my crystal ball here a bit.
One reason why the print in the for row in testReader: loop isn't working is that getcsv may already processes the file. Use the seek method to reset the objects position in the file to zero again. That way the for loop will process it properly.
Another reason why there's nothing stored in the database might be that in the code you've supplied there doesn't seem to be a reference to a model. So how should Django know what it should store and where?

Categories