How to test uploadfile in django - python

I have an uploadform and I want to test it. But there is a problem.
def test_if_can_upload_file(self):
with open('app_blog/tests/test.txt') as file:
self.client.post(reverse('csv_blog'), {'attachment': file})
test_file = file.read()
self.assertEqual(test_file, 'test file')
When I test it, there is an error:
self.assertEqual(test_file, 'test file')
AssertionError: '' != 'test file'
+ test file
Why is my file shown like it is empty? Actually it is not empty.Or maybe I test my form in a wrong way?
form
class UploadBlogForm(forms.ModelForm):
file = forms.FileField()
class Meta:
model = Blog
fields = 'file',
view
def upload_blog(request):
if request.method == "POST":
upload_file_form = UploadBlogForm(request.POST, request.FILES)
if upload_file_form.is_valid():
blog_file = upload_file_form.cleaned_data['file'].read()
blog_str = blog_file.decode('utf-8').split('\n')
csv_reader = reader(blog_str, delimiter=":::", quotechar='"')

Your self.client.post(…) will already exhaust the file handler and read the entire content of the file, this thus means that when you call file.read(), the cursor already moved to the end of the file, and thus returns an empty string.
You should reopen the file and read the file from the beginning, so:
def test_if_can_upload_file(self):
with open('app_blog/tests/test.txt') as file:
self.client.post(reverse('csv_blog'), {'attachment': file})
with open('app_blog/tests/test.txt') as file:
test_file = file.read()
self.assertEqual(test_file, 'test file')

Related

PYTHON: Upload text file then split into smaller text files in every n lines

I'm having a problem splitting my file. This is my code for uploading a file.
def upload_file(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
file = request.FILES['file']
return HttpResponse(str(file) + "is uploaded")
else:
form = UploadFileForm()
return render(request, 'upload.html',{'form':form})
I don't have any idea how to split the file that was uploaded. Like in every 20 lines, it'll split into smaller text files like this: File(1).txt, File(2).txt.... Thanks in advance!
def break_file(filepath,lines):
file=None
with open(filepath) as largefile:
for n,text in enumerate(largefile): #goes through each line
if n%lines ==0 :
if file: #check if previous file is already open.
file.close()
file_num = 1+ n/lines # 1 if you want file name to start from1
file_name = 'File({}).txt'.format(file_num)
file= open(file,"w")
file.write(text)
if file:
file.close()

File handling in django

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 :)

How download file and save it inside the upload folder using Django and Python

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.

Django request XML file

Hi I'm trying to send a XML file from one view to another.
First view (In this view I send the XML):
def view1(request):
xml_file = open("/path/to/respuesta_error.xml", "rb").read()
r = urllib2.Request("http://localhost:8000/ingram/response/", data=xml_file, headers={'Content-Type': 'text/xml'})
u = urllib2.urlopen(r)
response = u.read()
return HttpResponse(response)
Second view (In this view I should read the XML):
#csrf_exempt
# https://docs.python.org/2/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element
def view2(request):
xml_file = open("/path/to/respuesta_error.xml", "rb") # <-- How can I read the request XML?
text = xml_file.read()
text = strip_ns(text)
file_new = open("ultima_respuesta.xml", "w")
file_new.write(texto)
file_new.close()
return HttpResponse("test")
With that, in view2 I read the file /path/to/respuesta_error.xml, I don't know what I should do to read the XML file sent by POST from view1.
I tried with request and request.body but doesn't work.
Thanks
I found that request.body contains the XML as a string, so the view2 should be like this:
#csrf_exempt
# https://docs.python.org/2/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element
def view2(request):
text = strip_ns(request.body)
file_new = open("ultima_respuesta.xml", "w")
file_new.write(texto)
file_new.close()
return HttpResponse("test")

Cant get text to append to file in python

Ok so this snippet of code is a http response inside of a flask server. I dont think this information will be of any use but its there if you need to know it.
This Code is suppose to read in the name from the post request and write to a file.
Then it checks a file called saved.txt which is stored in the FILES dictionary.
If we do not find our filename in the saved.txt file we append the filename to the saved file.
APIResponce function is just a json dump
At the moment it doesn't seem to be appending at all. The file is written just fine but append doesn't go thru.
Also btw this is being run on Linino, which is just a distribution of Linux.
def post(self):
try:
## Create the filepath so we can use this for mutliple schedules
filename = request.form["name"] + ".txt"
path = "/mnt/sda1/arduino/www/"
filename_path = path + filename
#Get the data from the request
schedule = request.form["schedule"]
replacement_value = schedule
#write the schedule to the file
writefile(filename_path,replacement_value)
#append the file base name to the saved file
append = True
schedule_names = readfile(FILES['saved']).split(" ")
for item in schedule_names:
if item == filename:
append = False
if append:
append_to = FILES['saved']
filename_with_space =filename + " "
append(append_to,filename_with_space)
return APIResponse({
'success': "Successfully modified the mode."
})
except:
return APIResponse({
'error': "Failed to modify the mode"
})
Here are the requested functions
def writefile(filename, data):
#Opens a file.
sdwrite = open(filename, 'w')
#Writes to the file.
sdwrite.write(data)
#Close the file.
sdwrite.close()
return
def readfile(filename):
#Opens a file.
sdread = open(filename, 'r')
#Reads the file's contents.
blah = sdread.readline()
#Close the file.
sdread.close()
return blah
def append(filename,data):
## use mode a for appending
sdwrite = open(filename, 'a')
## append the data to the file
sdwrite.write(data)
sdwrite.close()
Could it be that the bool object append and the function name append are the same? When I tried it, Python complained with "TypeError: 'bool' object is not callable"

Categories