Django - difficulty in image upload using forms - python

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?

Related

Django updating profile photo

Look I have a problem with displaying photos after updating.
I have a function from my views.py
def addHW(request):
if request.user.is_authenticated:
obj = Profile.objects.get(user=request.user.id)
else:
obj = ''
profile = request.user.profile
form = CustomerForm(instance=profile)
template = 'HW/add.html'
context = {'form': form, 'profile': obj}
if request.method == 'POST':
form = CustomerForm(request.POST, request.FILES, instance=profile)
if form.is_valid():
Profile.objects.get(user=request.user.id).photo.delete()
form.save()
return render(request, template, context)
and after deleting previous photo and saving of new photo, page must be reloaded. And page shows visual reloading, but HTML shows src of previous image. And after manual refreshing page displays new src of photo.
How i can resolve it?
In case of a successful post, you need to make a redirect to implement the Post/Redirect/Get pattern. – Willem Van Onsem 32 mins ago

Django validator not triggering on file upload

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.

forms.FilePathField doesn't work

I'm very new to django and python. I'm trying to display the list of files in a folder on my system using FilePathField like this below but for some reason, no files are displayed. I tried in many different ways but nothing worked. All I need is to get the name of the file selected. Can somebody please help me?
forms.py
class PostForm(forms.Form):
content = forms.CharField(max_length=256)
created_at = forms.DateTimeField()
file = forms.FilePathField(path='C:\input')
Here is my views.py
def post_form_upload(request):
if request.method == 'GET':
form = PostForm()
else:
# A POST request: Handle Form Upload
form = PostForm(request.POST, request.FILES)
return render(request, 'polls/post_form_upload.html', {
'form': form,
})

Upload file with Django Views

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

simple django code snippet from file upload

sorry for dumb question.
def upload_file(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
handle_uploaded_file(request.FILES['file'])
return HttpResponseRedirect('/success/url/')
else:
form = UploadFileForm()
return render_to_response('upload.html', {'form': form})
what happens really in the background when i bind the request to the Form?
It creates an empty form to be passed to the template upload.html since the previous form in upload.html did not pass the validation. When a form has some error, Validation Error exception is raised, then the form is invalid, or when the view is called and request does not include the method POST therefor you must render it again.

Categories

Resources