I am writing a file upload page with Django/Python. I get this error:
FileNotFoundError: [Errno 2] No such file or directory: '48.png'.
Here is the relevant part of the view, which handles the upload:
`if request.method == 'POST':
form = myform(request.POST, request.FILES)
if form.is_valid():
print("FORM VALID")
f = request.FILES['thefile']
print("f:" + f.name)
print(pref+'/'+str(f))
open(f.name, 'rb')
else:
print('FORM NOT VALID')
Things go wrong in the open(f.name statement. The form is in a template:
<form method="post" action="/dataset_storage_upload/{{ pk }}/{{pid}}/" name="submit" enctype="multipart/form-data">
{% csrf_token %}
{{ theForm.as_p }}
<button type="start_upload" value="Submit" onclick="document.upload.submit() ">Upload</button>
</form>
and this is the form:
class myform(forms.Form):
thefile = forms.FileField()
I have this information in the console
FORM VALID
f:48.png
/17/3/48.png
(/17/3 is the prefix)
In the Traceback, in the browser, under local vars, I have this:
pref '/17/3'
mylist[]
f <InMemoryUploadedFile: 48.png (image/png)>
pk '17'
form <myform bound=True, valid=True, fields=(thefile)>
request<WSGIRequest: POST '/dataset_storage_upload/17/3/'>
I think this tells me that there is a file 48.png in memory. So why is it not there when I open it?
Many thanks for your attention.
It's only there in memory, not on the actual filesystem. Django File objects provide a wrapper around both real files, and in-memory files.
For example, if you were handling a file that was coming from a FileField on some model, what you're doing would work, but the file you're handling doesn't yet exist on the system.
If you want to read the file in your view, you can just call File.read:
f = request.FILES['thefile']
contents = f.read()
By default, if an uploaded file is smaller than 2.5 megabytes, Django
will hold the entire contents of the upload in memory. This means that
saving the file involves only a read from memory and a write to disk
and thus is very fast.
I changed f.open( into f.read( and now it works perfectly. For completeness: My goal is to store the uploaded file in S3, so that now I do
s3.Object('mybucket', str(pk)+'/'+str(p)+'/'+str(f)).put(Body=f.read(),Metadata={'project': '17','dataset':'3','filename':str(f)})
and this works.
Related
I am learning django. I am stuck with this problem.
The problem is that form.is_valid() always returns false.
I tried to debug and I think that the problem is because of "This field is required" error and I think that the field is file_name. I tried to resolve the issue but I am unable to do so.
Just to give a context of what I am trying to do -
I have created a form in which a user uploads a text file and selects a gender.
In the backend I want to save the name of the text file along with the gender in a model. The purpose of doing this is because when multiple users will use the application, I should know which user selected what gender so that I can produce the desired output.
Here is the link to my git repository -
git repository
As I already said I am new to django and some help will be appreciated.
Your fields in form are fields = ['file_name','gender'] and in the template you have
<label for="myfile"> <b> Select a file: </b> </label> <br/>
<input type="file" name="document"> <br/><br/>
<br/><br/>
{{ form.gender }}
... fields document and gender, no file_name. Add {{ form.file_name }} to the template or, if you want to stick to manually writing code for input, file input with a name file_name. Input names need to match field names in form.
Also, read this: Working with forms.
I think you are not saving the form. In your views line 24 you have
if request.method == 'POST':
form = TranscriptForm(request.POST)
return HttpResponse(str(form.errors))
If you are posting you will always return there,therefore there is no check for is_valid().
Same as line 60:
context = {'form': TranscriptForm()}
return render(request, 'tutorial/upload.html', context)
you havent accessed/saved the form yet for it to be valid
I have this view:
def index(request):
file = open("SK ✌😜✌.txt", encoding="UTF-8")
data = file.read()
file.close()
lines = data.split("\n")
...More code...
In this view i open a file from the very first moment the app starts and i do some work on the file, is a story, and when i start the server and go to http://127.0.0.1:8000/(Name Of The App), i see all the work that i have done on that file.
What i want to do is to do that same work, starting with the reading of the file, BUT i want to do that with the file that the user uploads in that moment. I have this that i took from bootstrap:
<div class="form-group">
<label for="exampleInputFile">File input</label>
<input type="file" id="exampleInputFile">
</div>
I guess i have to use in some way the id of the input but i`m not really sure how to pass this file that the user uploads in the ui to the method that i have in my views.py
Any help will be really appreciated
You need to have a name attribute in your <input> template code.
<input type="file" id="exampleInputFile" name="some_file">
Then to access the file in your view, you need to use request.FILES attribute.
As per the Django docs on HttpRequest.FILES attribute:
A dictionary-like object containing all uploaded files. Each key in
FILES is the name from the <input type="file" name="" />. Each
value in FILES is an UploadedFile.
Your code should be something like:
def index(request):
if request.method=="POST":
uploaded_file = request.FILES['some_file'] # get the uploaded file
# do something with the file
Note: request.FILES will only contain data if the request method was POST and the <form> that posted to the request had enctype="multipart/form-data. Otherwise, FILES will be a blank dictionary-like object.
I have spent a LOT of time trying to resolve this- Read Django docs, consulted forms but not got anything satisfactory. So please be patient here with me.
I am trying to do an upload of an Image file here from my html template.
This is my html form
<form id="tryOnPageForm" method="POST" enctype="multipart/form-data" action="/dummy/{{frame.slug}}/">
{% csrf_token %}
<input type="file" name="uploadFromPC" id="uploadFromPC" class="myButton" title="Upload From PC" value= "Upload from PC" onchange="uploadPC()" style="float:left;">
<input type="submit" id="Submit" class="myButton" value= "Done" style="display:none"><br><br>
</form>
The file upload happens properly an d I am able to see the uploaded image file in the HTML.
In my views.py,
def upload_image(request, frameslug):
frame= v.objects.get(slug=frameslug)
if request.method == 'POST':
form = ImageUploadForm(request.POST, request.FILES)
print "FILES", request.FILES
if form.is_multipart():
save_file(request.FILES['image'])
return HttpResponseRedirect('Successful')
else:
return HttpResponse('Invalid image')
else:
form = ImageUploadForm()
return render_to_response('dummy.html', {'form': form})
def save_file(file, path=''):
''' Little helper to save a file
'''
filename = file._get_name()
fd = open('%s/%s' % (MEDIA_ROOT, str(path) + str(filename)), 'wb')
for chunk in file.chunks():
fd.write(chunk)
fd.close()
and in my forms.py,
from django import forms
class ImageUploadForm(forms.Form):
image = forms.ImageField(label='Select a file', help_text='max. 20 megabytes')
When I run my code I get this error
MultiValueDictKeyError at /dummy/fr1234/
The print statement in my from my view.py shows this
FILES <MultiValueDict: {u'uploadFromPC': [<InMemoryUploadedFile: model4.jpg (image/jpeg)>]}>
and this is the traceback
Traceback:
File "C:\Python27\lib\site-packages\django\core\handlers\base.py" in get_response
112. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "D:\Work-Backup\LiClipse Workspace\vTryON_DJango_Integration\vTryON\views.py" in upload_image
189. save_file(request.FILES['image'])
File "C:\Python27\lib\site-packages\django\utils\datastructures.py" in __getitem__
301. raise MultiValueDictKeyError(repr(key))
Exception Type: MultiValueDictKeyError at /dummy/fr1234/
Exception Value: "'image'"
I am aware that the enctype should be multipart/form-data since I have read it in tutorials. ALso, i have not used any field in my models.py to store the uploaded image.Instead I want to directly save it to thr MEDIA_URL location.Might that be an issue?
Please help. This has held me up for a long time. Thanks in advance.
I was able to solve this(after spending a lot of time and with some help from my friends...)
I think the error
Exception Type: MultiValueDictKeyError at /dummy/fr1234/
Exception Value: "'image'"
was coming because request.FILES was unable to get the uploaded image from the user input, the reason being that the name of the user input file that I provided was wrong!!
It should have been request.FILES['uploadFromPC'] instead of request.FILES['image'] because that is the name that I had kept in my HTML.
<input type="file" name="uploadFromPC" id="uploadFromPC" class="myButton" title="Upload From PC" value= "Upload from PC" onchange="uploadPC()" style="float:left;">
That was a stupid error and a lot of time wasted to fix it.. :(
.. but ya, good learning.
I hope this helps somebody else who is trying to do something similar. Although, I would like it if somebody can explain to me the use of forms.py here.
Is it possible to do an user upload without forms.py?
I found that the error occurs when you submit the form without selecting the file. when a file is not selected then the input_name in your case image is u''. this gives the error as the dictionary has no such key.
i tried to find a way to try and except error but there is no such exception in python MultiValueDictKeyError
request.FILES['file1']
raises the multivaluedictkeyerror, so please check if you have the files under request.FILES like below -
if request.method == "POST" and 'file1' in request.FILES and 'file2' in request.FILES:
Don't use
if request.method == "POST" and request.FILES['file1']:
as it also raises error
I need to know it to correctly get filedata from POST dictionary.
I want to use Agile Uploader (resizes images on client side before upload on the server) in my project. It has process.php file as example of handling image on server. In that file:
$tmp_name = $_FILES["Filedata"]["file_name"]; // where "tmp_name" is file name
As Pyramid doesn't have FILES dictionary, I supose I have to find image in POST. But when I try to upload image POST is empty...
So where it send that image and how to find it on server side?
HTML (most part of html code taken from their demo):
<form action="/test" method="post" id="singularDemo" enctype="multipart/form-data">
<div id="single"></div>
</form>
Submit
<script type="text/javascript">
$('#single').agileUploaderSingle({
submitRedirect:'',
formId:'singularDemo',
progressBarColor:'#3b5998',
flashVars:{
firebug:true,
form_action:'/test'
}
});
</script>
Python (Pyramid code), just for testing - simple view:
def test(request):
if request.method == 'POST':
pass
return {}
Thanks!
Since the $_FILES global contains files submitted by a POST request, you can access them using request.POST:
# access the filename
filename = request.POST['Filedata'].filename
# access the actual file
input_file = request.POST['Filedata'].file
This is an exact equivalent of the PHP $_FILES variable, so if it doesn't work, something else must be wrong.
The Pyramid cookbook has more information about file uploads.
<input type="file" name="doc-file" multiple/>
file_path = request.FILES.get('doc-file')
My return value of file_path is None
But when I do file_path = request.POST.get('doc-file') it returns filename . What is the best way to upload a file in python and django?
It sounds like you might be forgetting to include enctype="multipart/form-data" in your form tag. See Django's docs on file uploads for details.
Edit: formatting