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?
Related
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.
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.
I am new to django and web programming. Right now, I have created a django project for configuration form generation. It allows the user to input the values and generate a configuration form once the user got the URL.
Project name: portal, App name: home, input_data.txt: a text file stored the values for the corresponding parameter and it will be read for further processing
It works fine for myself, but multiple users use it at the same time. It doesn't work. what can I do in order to allow multiple users use it at the same time?
forms.py
from django import forms
from .models import FormGen
from .models import BB_Data
class FinalForm(forms.ModelForm):
class Meta:
model=FormGen
field=['full_name','backbone_number']
class BBForm(forms.ModelForm):
class Meta:
model=BB_Data
fields=['backbone_name','IP','numbers']
widget={'numbers':forms.TextInput(attrs={'readonly':'readonly'})}
views.py
from django.shortcuts import render,HttpResponse,redirect
from .forms import FinalForm,BBForm
from django.core.files import File
import re
def replacePara(template,para):
for key,val in para.items():
template=template.replace(key,val)
return template
def create(request):
title="Router Generator"
form=FinalForm(request.POST or None)
context={
"template_title":title,
"form":form,
}
if(form.is_valid()):
form_data={
"HNAME":form.cleaned_data.get("Hostname"),
"ROLE":form.cleaned_data.get("Router_Role"),
}
form.save()
f=open('./input_para.txt','r')
a=f.read();
f.close();
tt=replacePara(a,form_data)
b=open('./input_data.txt','w')
b.write(tt)
b.close()
return redirect('/backbone')
return render(request,"home/form.html",context)
def bb(request):
title="Backbone Information"
if request.method=="POST":
form=BBForm(request.POST)
if form.is_valid():
bb_form={
'BBNAME':form.cleaned_data.get('backbone_name'),
'BBIP':form.cleaned_data.get('IP'),
}
a=int(form.cleaned_data.get('numbers')
datainput=''
if a==1:
f=open('./bb_set.txt','w')
f.write(bb_form)
f.close()
else:
f=open('./bb_set.txt','a')
outBB.write(bb_form)
outBB.close()
form.save()
f=open('./input_data.txt','r')
t=f.read()
tt=int(t.split()[7]) #it get the max number of backbones
if(at<tt):
at=at+1;
bb=BBForm(initial={'numbers':str(at)})
context={
"template_title":title,
"form":bb
}
return render(request,"home/bb.html",context)
else:
# generate the configurate text file #
content=final # content store the configurations
filename="ConfigForm.txt"
response=HttpResponse(content,content_type='text/plain')
response['Content-Disposition']='attachment; filename={0}'.format(filename)
return response
else:
return HttpResponse("something wrong")
else:
form=BBForm(initial={'numbers':"1"})
f=open('./input_data.txt','r')
t=f.read()
tt=int(t.split()[7])
context={
'template_title':title,
'form':form,
'max':tt
}
return render(request,"home/bb.html",context)
input_para: it is the text file stored the name of the parameter
input_data: it is the text file stored the values for correspond parameter
bb_set: it is the text file stored all the backbone information
You're saving data to a single file, with no regards as to users. If I go to your website, I'll be writing to the same input_data.txt, input_para.txt, and bb_set.txt files as anyone else also visiting.
This is not the way to persist user data for a website/service. You should be using a database.
Luckily, you're using Django, which has phenomenal database integration, and it's actually really easy. The hardest part, for you, will be designing the database. You'll want a User model, against which you can record input_data, input_para, and bb_set data against, from what I can tell.
I recommend you follow the Django tutorial, specifically this section, and perhaps also read up on database design, (including normalisation of data, which is more interesting than it sounds).
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.
I have a typical models.ModelForm that has a single field: a FileField. However, when the user uploads a file using the form and the page reloads, the file is not listed. The user has to reload the page manually for it to appear as the "current file."
This is my view code:
submission = Submission.objects.filter(user=request.user, problem=problem).first()
if request.POST:
submission_form = SubmissionForm(request.POST, request.FILES, instance=submission)
if submission_form.is_valid():
submission_form.save()
else:
submission_form = SubmissionForm(instance=submission)
return render_to_response('view-problem.html',
dictionary={'problem': problem, 'submission_form': submission_form},
context_instance=RequestContext(request))
My guess is that the file is still being processed while the view is loaded, so the user doesn't immediately see it. How do I fix this?
You have to create a new form after saving the old form.ModelForm.save() returns a model instance, you can use this instance to initialize the new ModelForm.
Code:
if request.POST:
submission_form = SubmissionForm(request.POST, request.FILES, instance=submission)
if submission_form.is_valid():
submission = submission_form.save()
submission_form = SubmissionForm(instance=submission)