I'm trying to save a file to disk, not in a class or anything just straight to disk but I can't for the life of me figure out how.
So far I've got:
View: `
def uploadview(request):
uploadtestvar='Uploadpage!'
request.session['test']='Is this working?'
if request.method == 'POST':
form=UploadForm(request.POST, request.FILES)
if form.is_valid():
forcetitle='test'
try:
pass
except:
pass
return HttpResponseRedirect('/test/')
else:
form=UploadForm()
return render(request, 'test/uploads.html',{'uploadtestvar':uploadtestvar, 'form':form})`
Form stolen directly from Django:
from django import forms
class UploadForm(forms.Form):
title=forms.CharField(max_length=50)
file=forms.FileField()
I've searched countless threads and found none that gives an example simple enough for me to understand how to get that request.FILES['file'] saved to disk somewhere. The possible filetypes are png, jpg, and pdf.
Pass FileSystemStorage to FileField in models where FileSystemStorage has the storage directory
from django.core.files.storage import FileSystemStorage
fs = FileSystemStorage(location = 'media/files/')
class UploadModel(models.Model):
title=forms.CharField(max_length = 50)
file=forms.FileField(storage = fs)
Related
I want to upload an image from django forms and process it using OpenCV. Here is the code I've written with the help of Django documentation:
1.forms.py:
class UploadFileForm(forms.Form):
image = forms.ImageField()
2.views.py:
def upload_file(request):
context = {'status':'not working'}
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
context['status'] = 'working'
process(request.FILES['test_01.png'])
return render(request,'create.html',context)
else:
form = UploadFileForm()
return render(request, 'create.html', {'form': form})
Here process() is the function which processes the uploaded image.Running this code gives me MultiValueDictKey Error on the line where I call process()
After searching for the error, referring to this SO answer I changed process(request.FILES['test_01.png']) to process(request.FILES.get('test_01.png')) I get Attribute Error on the same line(which I guess is because I'm not able to retrieve the uploaded image properly)
Where am I going wrong and what is the correct way of doing so?
I am new to python and programming in general.
I keep getting UploadNotAllowed error even though I set the form field validator to Optional(). My goal is to allow users the choice of uploading or not uploading a profile picture. All configurations work well when an image if selected to be uploaded.
Any help will be appreciated.
Here is the form field:
class SettingsForm(FlaskForm):
profile_pic = FileField('Profile Picture', validators= [Optional(), FileAllowed(images, 'Only images are allowed here')])
Here is my views.py:
if form.validate_on_submit():
filename = images.save(request.files['profile_pic'])
current_user.profile_pic = images.url(filename)
this is a slightly edited version from the docs (here). Which also give you some reminders about what your html file should contain.
from flask_wtf import FlaskForm
from flask_wtf.file import FileField, FileRequired
from werkzeug.utils import secure_filename
class PhotoForm(FlaskForm):
photo = FileField(validators=[Optional(), FileAllowed(images, 'Only images are allowed here')])
#app.route('/upload', methods=['GET', 'POST'])
def upload():
if form.validate_on_submit():
f = form.photo.data
filename = secure_filename(f.filename)
#you can replace this with wherever you want to save your images
f.save(os.path.join(
app.instance_path, 'photos', filename
))
current_user.profile_pic = images.url(filename)
return redirect(url_for('index'))
return render_template('upload.html', form=form)
I have wrote a Django app for the user to upload files and see a list of uploaded files. I want to restrict the uploads to only using gif format and wrote a simple validator. Then I pass that validator in the Model, however it never triggers and the file is saved regardless of the format. Here's what I got so far.
views.py
def list(request):
# Handle file upload
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
newdoc = Document(docfile=request.FILES['docfile'])
newdoc.save()
messages.add_message(request, messages.INFO, "Saved")
# Redirect to the document list after POST
return HttpResponseRedirect(reverse('list'))
else:
form = DocumentForm() # A empty, unbound form
# Load documents for the list page
documents = Document.objects.all()
# Render list page with the documents and the form
return render(
request,
'list.html',
{'documents': documents, 'form': form}
)
checkformat.py
def validate_file_type(upload):
if not (upload.name[-4:] == '.gif'):
raise ValidationError('File type not supported.')
models.py
from .checkformat import validate_file_type
def content_file_name(instance, filename):
return '/'.join(['documents', str(filename), filename])
class Document(models.Model):
docfile = models.FileField(upload_to=content_file_name, validators=[validate_file_type], null=False, verbose_name="File")
forms.py
class DocumentForm(forms.Form):
docfile = forms.FileField(
label='Select a file', widget=forms.FileInput(attrs={'accept':'image/gif'})
)
Is there something I'm missing? I've just started learning Django. Also, I know this is not a sercure way to check for a file type, but I just want to see it work to continue. Thank you for your time.
if form.is_valid():
newdoc = Document(docfile=request.FILES['docfile'])
if not '.gif' in newdoc.name:
raise ValidationError('File type not supported.')
else:
newdoc.save()
messages.add_message(request, messages.INFO, "Saved")
try this simple solution, hope it works as you need
Looks right so far. Maybe it's simply a lower/upper case issue?
A more accurate solution might be:
import os
def validate_file_type(upload):
if os.path.splitext(upload.name)[1].lower() != '.gif':
raise ValidationError('File type not supported.')
If it's still not working try to add a break point within the validation method and check the value of upload.name.
I think the problem is the form is derived from a simple Model class, but in your case you must use ModelForm instead.
This way the form knows about the Document model, and you can do some fancy operations, like calling the save mehond in the Form object so save the model instance. Also the is_valid method calls all the validations defined in the model, in addition to the validations defined in the Form itself.
I am working on a feature for a Django application that uploads files (images in my context) to the server. Everything is working fine but I am wondering how I can receive as callback the uploaded file path.
Here is my View:
def post(self, request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
handle_uploaded_file(request.FILES['uploadedFile'])
return redirect('/')
else:
form = UploadFileForm()
return render_to_response('index.html', {'form': form})
My Form:
class UploadFileForm(forms.Form):
uploadedFile = forms.FileField()
And my handler:
def handle_uploaded_file(source):
fd, filepath = tempfile.mkstemp(prefix=source.name, dir=FILE_UPLOAD_DIR)
with open(filepath, 'wb') as dest:
shutil.copyfileobj(source, dest)
return filepath
I know that handle_uploaded_file(request.FILES['uploadedFile']) from my view is the required string that I need as callback but how to receive it in the response?
It is possible to receive instead of my index.html (it is there just for testing purposes) the path of the image for further manipulation in the frontend part.
I might sound like a noob but I really want if that works somehow.
Also is there a way for my View to handle multiple file upload? It is something that I need to change in my handler?
Sorry for putting so many questions...
Try this:
file_path = handle_uploaded_file(request.FILES['uploadedFile'])
return render_to_response('index.html', {'form': form, 'file_path': file_path})
I'm sooo close... but I don't quite see the connection from the upload view to the model. When I use the callback in the model's FileField the upload works, but I'm not sure where the actual file copy is taking place. The goal is to make sure that chunking is happening, but the file copy action seems to be hidden somewhere?
Here's what I have:
Model:
def get_media_upload_dir(instance, filename):
user_id = instance.user.id
upload_dir = "%s/%d/%s" % (settings.MEDIA_ROOT, user_id, filename)
print "Upload dir set to: %s" % upload_dir
return upload_dir
class MediaFile(models.Model):
media_file = models.FileField(upload_to=get_media_upload_dir)
download_count = models.PositiveIntegerField(default=0)
View:
def file_upload(request, course_id):
if request.method == 'POST':
form = FileUploadForm(request.POST, request.FILES)
if form.is_valid():
uploaded = form.cleaned_data['file_upload']
mediaFile = MediaFile(media_file=uploaded,
owner=request.user.profile,
creator=request.user.profile)
mediaFile.save()
return HttpResponseRedirect('/course/%s/' % course_id)
else:
form = FileUploadForm()
return render_to_response('course/file_upload.html', {'form':form,'course':course}, context_instance=RequestContext(request))
The storing happens here: http://code.djangoproject.com/browser/django/trunk/django/db/models/fields/files.py#L90. Django uses it's own API for accessing the file storage: http://docs.djangoproject.com/en/dev/ref/files/storage/. But if chunking is what you need you can go with Bartek's proposal!