I need user to upload an excel file via the form provided and i need to process that uploaded excel file to save the data in my model.
models.py
class Patient_Record(models.Model):
Patient_id=models.IntegerField(unique=True)
Patient_sex=models.CharField(max_length=1,choices=Gender)
Patient_name=models.CharField(max_length=20)
Patient_sugar=models.DecimalField(decimal_places=3,max_digits=6)
Patient_chlorestrol=models.DecimalField(decimal_places=3,max_digits=6)
Patient_iron=models.DecimalField(decimal_places=3,max_digits=6)
Patient_haemoglobin=models.DecimalField(decimal_places=3,max_digits=6)
def __str__(self):
return self.pat_name
I have simple form to upload the file.
<form method="POST" class="post-form" action="../Uploaded_file" enctype="multipart/form-data" name="myfile">{% csrf_token %}
{{ upload_form.as_p }}
<input type="submit" value="Upload" name="Upload" class="btn btn-primary">
</form>
Can someone help me with the code to parse a excel file using POST to this model.
I tried using many different methods but couldn't succeed in it.
You require xlrd library to extract the data from excel sheet.
Check out following link https://pypi.python.org/pypi/xlrd
This is the example snippet. You may modify it according to your code.
In Forms.py create a model form with following field.
class UpdateDetailsForm(forms.Form):
excel_file = forms.FileField(label='Excel File',required=False,validators=[validate_file_extension])
Then in corresponding views.py
def update_details(request):
message=''
if request.method == 'POST':
form = UpdateDetailsForm(request.POST,request.FILES)
if form.is_valid():
#import your django model here like from django.appname.models import model_name
excel_file = request.FILES['excel_file']
i=0
try:
import os
import tempfile
import xlrd
fd, tmp = tempfile.mkstemp()
with os.fdopen(fd, 'w') as out:
out.write(excel_file.read())
book=xlrd.open_workbook(fd)
sh = book.sheet_by_index(0)
for rx in range(1,sh.nrows):
obj=Patient_Record(Patient_id=str(sh.row(rx)[0].value),Patient_sex=str(sh.row(rx)[1].value)) # similiary populate according to your model
obj.save()
i=i+1;
finally:
os.unlink(tmp)
else:
message='Invalid Entries'
else:
form = UpdateDetailsForm()
return render_to_response('admin/import_data.html', {'form':form,'message':message},context_instance=RequestContext(request))
In Python 3.6 and Django 2.0 the following rises the error
Exception Type: PermissionError
Exception Value:[WinError 32]
def upload_file(request):
message=''
if request.method == 'POST':
form = FormUploadFileData(request.POST, request.FILES)
if form.is_valid():
from projects.models import Project
excel_file = request.FILES['excel_file']
try:
import os
import tempfile
import xlrd
fd, tmp = tempfile.mkstemp() # create two temporary file
with os.open(fd, 'wb') as out: # create new file objects
out.write(excel_file.read())
book = xlrd.open_workbook(fd)
sheet = book.sheet_by_index(0)
obj=Project(
project_title = sheet.cell_value(rowx=1, colx=1),
project_sector = sheet.cell_value(rowx=2, colx=1),
project_location = sheet.cell_value(rowx=3, colx=1),
project_tot_cost = sheet.cell_value(rowx=4, colx=1),
project_descr = sheet.cell_value(rowx=5, colx=1),
project_fund = sheet.cell_value(rowx=6, colx=1),
project_cofin = sheet.cell_value(rowx=7, colx=1),
project_applicant = sheet.cell_value(rowx=8, colx=1)
)
obj.save()
finally:
os.unlink(tmp)
else:
message='Invalid Entries'
else:
form = FormUploadFileData()
return render(request,'upload.html', {'form':form,'message':message})
There is an issue in the solution proposed:
book=xlrd.open_workbook(fd) should be book=xlrd.open_workbook(tmp) as open_workhook search for a file path
[Worked in Python 3.6, Django 2.0]
excel_file = request.FILES['excel_file']
import os
import tempfile
import xlrd
fd, path = tempfile.mkstemp() # mkstemp returns a tuple: an integer (index) called file descriptor used by OS to refer to a file and its path
try:
with os.fdopen(fd, 'wb') as tmp:
tmp.write(excel_file.read())
book = xlrd.open_workbook(path)
sheet = book.sheet_by_index(0)
obj=Project(
project_title = sheet.cell_value(rowx=1, colx=1),
project_sector = sheet.cell_value(rowx=2, colx=1),
project_location = sheet.cell_value(rowx=3, colx=1),
project_tot_cost = sheet.cell_value(rowx=4, colx=1),
project_descr = sheet.cell_value(rowx=5, colx=1),
project_fund = sheet.cell_value(rowx=6, colx=1),
project_cofin = sheet.cell_value(rowx=7, colx=1),
project_applicant = sheet.cell_value(rowx=8, colx=1)
)
obj.save()
finally:
os.remove(path)
Related
I am trying to access the csv file which i passed in my form and saved in media directory.
I am able to access the file if i manually enter the path(localhost://8000/media/1.csv)
but it throws an error saying "No such file or directory" when accessing from open function.
def home(request):
print("Rendering Home...")
if request.method == "POST":
uploaded_file = request.FILES['csvFile']
fs = FileSystemStorage()
name = fs.save(uploaded_file.name,uploaded_file)
url = fs.url(name)
csv_fp = open(f'{url}', 'r') //ERROR:"No such file or dir media/1.csv"
reader = csv.DictReader(csv_fp)
headers = [col for col in reader.fieldnames]
out = [row for row in reader]
return render(request, 'home.html', {'data' : out, 'headers' : headers})
return render(request,"home.html")
have you tried .path instead of .name
file = open(filename.path' 'rb').read()
The problem was the path being given to open function
csv_fp = default_storage.open(os.path.join(settings.MEDIA_ROOT, name), 'r')
simply did the trick :)
I am trying to save a file and do something to it a from in an html file, I am not using django forms but I am using django for backend and I don't need a database since I don't want to keep any of the files. I tried what the django documentation has instructed.
html file
<input type="file" id="face_files" name="face_files" multiple >
view.py
def index(request):
if request.method == "GET":
return render(request, 'index.html')
if request.method == "POST":
form = InputForm(request)
call_form_function(form)
return render(request, 'index.html')
Inputform.py
class InputForm():
def __init__(self, request):
self.face_files = request.FILES.getlist('face_files')
# print('face_files= ', self.face_files)
self.face_name = request.POST.get('face_name')
# print('face_name= ', self.face_name)
def save_files(self):
import os
self.delete_temp()
folder = os.path.dirname(__file__) + '/static/temp/'+self.face_name
try:
os.mkdir(folder)
counter=1
for file in self.face_files:
# print(file)
destination=open(folder +"/face"+str(counter)+".jpg", 'wb+')
for chunk in file.chunks():
destination.write(chunk)
destination.close()
counter+=1
except:
with open(console_html_path, "w+") as f:
f.write(traceback.format_exc())
traceback.print_exc()
return folder
def do_function(self):
folder_path = self.save_files()
function(args, folder_path)
def call_form_function(form):
import threading
t1 = threading.Thread(target=form.do_function)
t1.start()
But I get the error
lib/python3.7/site-packages/django/core/files/uploadedfile.py", line 91, in chunks
self.file.seek(0)
ValueError: I/O operation on closed file.
what am I doing wrong?
You can create a separate function to handle the uploaded file.
def handle_uploaded_files(f):
with open(f'uploaded/folder/path/{f.name}', 'wb+') as destination:
for chunk in f.chunks():
destination.write(chunk)
I want to upload a file, what I am able to do with the code stated below, but I also need to save all the uploads in different folder with different names. If 2 users upload the same file from browser, then in the folder it should be saved with different name or Unique Identification number.
Following is my code:
views.py
from django.shortcuts import render
import openpyxl
def index(request):
if "GET" == request.method:
return render(request, 'myapp/index.html', {})
else:
excel_file = request.FILES["excel_file"]
# you may put validations here to check extension or file size
wb = openpyxl.load_workbook(excel_file)
# getting all sheets
sheets = wb.sheetnames
print(sheets)
# getting a particular sheet
worksheet = wb["Sheet1"]
print(worksheet)
# getting active sheet
active_sheet = wb.active
print(active_sheet)
# reading a cell
print(worksheet["A1"].value)
excel_data = list()
# iterating over the rows and
# getting value from each cell in row
for row in worksheet.iter_rows():
row_data = list()
for cell in row:
row_data.append(str(cell.value))
print(cell.value)
excel_data.append(row_data)
return render(request, 'myapp/index.html', {"excel_data":excel_data})
Give you a Django FileField way Implemention:
def user_directory_path(instance, filename):
# file will be uploaded to MEDIA_ROOT/user_<id>/<filename>
suffix = filename[filename.rindex(".")+1:]
return 'upfiles/{0}/{1}.{2}'.format(instance.user.username, get_randomfilename(),suffix)
class Picture(models.Model):
user = models.ForeignKey(User,on_delete=models.CASCADE)
file = models.ImageField(upload_to=user_directory_path)
date_added = models.DateTimeField(auto_now_add=True)
#parser_classes((MultiPartParser,))
#permission_classes((IsAuthenticated, ))
def upload_picture(request):
'''
:input :{"file":f}
:return:{"id":pictureId}
'''
if "file" in request.FILES:
f = request.FILES["file"]
picture = Picture()
picture.user= request.user
picture.file = f
picture.save()
return Response(data={"id":picture.id})
else:
return Response({},status=status.HTTP_400_BAD_REQUEST)
I am trying to write the content in CSV file and Here I need to download that file and save that same file into upload folder. My code is below.
if request.method == 'POST':
param = request.POST.get('param')
report = Reactor.objects.all()
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename='+uuid.uuid4()+'.csv'
writer = csv.writer(response)
writer.writerow(['Name', 'Status', 'Date'])
for rec in report:
if rec.status == 1:
status = 'Start'
if rec.status == 0:
status = 'Stop'
if rec.status == 2:
status = 'Suspend'
writer.writerow([rec.rname, status, rec.date])
#return response
u = urllib.URLopener()
f = u.open(param)
open("down.txt","w").write(f.read())
pers = User.objects.get(pk=request.session['id'])
root = []
user_name = pers.uname
count = 1
root.append(
{'username': user_name,
'count': count
})
return render(request, 'plant/home.html',
{'user': root, 'count': 1})
Here I am setting the database values inside one CSV file and that file is named as unique id. Here I need to save that file inside Upload folder and that folder path will set inside settings.py file and also same file will be downloaded as well.
You should try to generate your CSV into a buffer an then use it to save it to the file system and use it again to return the CSV as the respone. Something like this
import csv
import os
import shutil
from io import StringIO
from django.http import HttpResponse
from django.conf import settings
def my_view(request):
csvbuffer = StringIO
writer = csv.writer(csvbuffer)
# Write data from the DB here into the CSV buffer
# Write the file to the file system
path = os.path.join(settings.FILE_PATH, "%s.csv" % uuid.uuid4())
with(path, 'w') as fd:
csvbuffer.seek(0)
shutil.copyfileobj(csvbuffer, fd)
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="somefilename.csv"'
csvbuffer.seek(0)
response.write(csvbuffer)
return response
I am quite sure this not the most optimized way to do it, but at least it should works.
I'm building a web app in Django.
I have a form that sends a file to views.py.
Views:
#login_required(login_url=login_url)
def addCancion(request):
if request.method == 'POST':
form2 = UploadSong(request.POST, request.FILES)
if form2.is_valid():
if(handle_uploaded_song(request.FILES['file'])):
path = '%s' % (request.FILES['file'])
ruta = "http://domain.com/static/canciones/%s" % path
usuario = Usuario.objects.get(pk=request.session['persona'])
song = Cancion(autor=usuario, cancion=ruta)
song.save()
return HttpResponse(ruta)
else:
return HttpResponse("-3")
else:
return HttpResponse("-2")
else:
return HttpResponse("-1")
I'm trying to upload only the MP3 files, but I don't know how to make this filter.
I tried a class named "ContentTypeRestrictedFileField(FileField):" and doesn't work.
How can I get the file type in views.py?
Thanks!
You could also use the clean() method from the form, which is used to validate it. Thus, you can reject files that are not mp3. Something like this:
class UploadSong(forms.Form):
[...]
def clean(self):
cleaned_data = super(UploadSong, self).clean()
file = cleaned_data.get('file')
if file:
filename = file.name
print filename
if filename.endswith('.mp3'):
print 'File is a mp3'
else:
print 'File is NOT a mp3'
raise forms.ValidationError("File is not a mp3. Please upload only mp3 files")
return file
with import mimetypes, magic:
mimetypes.MimeTypes().types_map_inv[1][
magic.from_buffer(form.cleaned_data['file'].read(), mime=True)
][0]
gives you the extension as '.pdf' for example
https://docs.djangoproject.com/en/dev/topics/forms/#processing-the-data-from-a-form
http://docs.python.org/2/library/mimetypes.html#mimetypes.MimeTypes.types_map_inv
https://github.com/ahupp/python-magic#usage
for get direct of request:
import os
extesion = os.path.splitext(str(request.FILES['file_field']))[1]
or get extesion in db - model.
import os
file = FileModel.objects.get(pk=1) # select your object
file_path = file.db_column.path # db_column how you save name of file.
extension = os.path.splitext(file_path)[1]
You mean this:
u_file = request.FILES['file']
extension = u_file.split(".")[1].lower()
if(handle_uploaded_song(file)):
path = '%s' % u_file
ruta = "http://example.com/static/canciones/%s" % path
usuario = Usuario.objects.get(pk=request.session['persona'])
song = Cancion(autor=usuario, cancion=ruta)
song.save()
return HttpResponse(content_type)
You can use request.FILES["file_field_name"].content_type
my_file = request.FILES["file_field_name"]
if my_file.content_type != 'text/csv':
print("Your file must be a CSV type")
Using FileType.py library.
Example:
kind = filetype.guess('tests/fixtures/sample.jpg')
if kind is None:
print('Cannot guess file type!')
return
print('File extension: %s' % kind.extension)
print('File MIME type: %s' % kind.mime)
Using MimeTypes().guess_extension() method. Check snippet below.
# guess the file extension
file_obj.seek(0)
mime = magic.from_buffer(file_obj.read(), mime=True)
extension = mimetypes.MimeTypes().guess_extension(mime)
>>> print extension
.jpeg