I'm trying to use dropzone.js with django.
I'm following the somewhat dated guide here (https://amatellanes.wordpress.com/2013/11/05/dropzonejs-django-how-to-build-a-file-upload-form/)
I strongly suspect My view is at issue.
def test(request):
print "test view has been called"
if request.method == 'POST':
print "test request method is POST"
form = UploadFileForm(request.POST, request.FILES)
print request
print request.FILES
if form.is_valid():
new_file = AttachedFiles(attachedfile=request.FILES['file'])
new_file.save()
id = new_file.pk
print id
print "test form valid"
return HttpResponse(json.dumps({'id': id}), content_type="application/json")
print "test form not valid"
else:
form = UploadFileForm()
data = {'form': form}
return render_to_response('mediamanager/test.html', data, context_instance=RequestContext(request))
I've tested submitting to it with the dropzone code
<!-- IMPORTANT enctype attribute! -->
<form id="my_dropzone" class="dropzone" action="/mediamanager/test/" method="post" enctype="multipart/form-data">
{% csrf_token %}
<button id="submit-all">
Submit all files
</button>
</form>
<script src="{% static 'dropzone/js/dropzone.js' %}"></script>
<script type="text/javascript">
Dropzone.options.myDropzone = {
// Prevents Dropzone from uploading dropped files immediately
autoProcessQueue : true,
init : function() {
var submitButton = document.querySelector("#submit-all")
myDropzone = this;
submitButton.addEventListener("click", function() {
myDropzone.processQueue();
// Tell Dropzone to process all queued files.
});
// You might want to show the submit button only when
// files are dropped here:
this.on("addedfile", function() {
// Show submit button here and/or inform user to click it.
console.log("blah")
});
}
};
</script>
and a basic form
<form action="{% url "test" %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="file" />
<input type="submit" value="Submit">
</form>
And the form is never valid.
I'm using a modelform as suggested
class UploadFileForm(forms.ModelForm):
class Meta:
model = AttachedFiles
You can handle Dropzone posts like any other multipart form post.
Here's how I proceed:
#login_required
#usertype_required
def upload_picture(request, uid=None):
"""
Photo upload / dropzone handler
:param request:
:param uid: Optional picture UID when re-uploading a file.
:return:
"""
form = PhotoUploadForm(request.POST, request.FILES or None)
if form.is_valid():
pic = request.FILES['file']
# [...] Process whatever you do with that file there. I resize it, create thumbnails, etc.
# Get an instance of picture model (defined below)
picture = ...
picture.file = pic
picture.save()
return HttpResponse('Image upload succeeded.')
return HttpResponseBadRequest("Image upload form not valid.")
The form is dead simple
class PhotoUploadForm(forms.Form):
# Keep name to 'file' because that's what Dropzone is using
file = forms.ImageField(required=True)
In your model you need the upload_to set:
class Picture(models.Model):
[...]
# Original
file = models.ImageField(upload_to=get_upload_path)
And here's my upload path builder, but you can put anything
def get_upload_path(instance, filename):
""" creates unique-Path & filename for upload """
ext = filename.split('.')[-1]
filename = "%s.%s" % (instance.p_uid, ext)
d = datetime.date.today()
username = instance.author.username
#Create the directory structure
return os.path.join(
'userpics', username, d.strftime('%Y'), d.strftime('%m'), filename
)
Don't forget the csrf_token in the html form itself (I'm using an angularJS directive on top of it so will be different for you)
<form action="{% url 'upload_picture' %}" class="dropzone" drop-zone>
{% csrf_token %}
<div class="fallback">
<h3>Your browser is not supported.</h3>
<strong>
Click here for instructions on how to update it.
</strong>
<p>You can still try to upload your pictures through this form: </p>
<p>
<input name="file" type="file" multiple />
<input type="submit" value="Upload" />
</p>
</div>
</form>
I got dropzone js working by modifying the bootstrap example (I am using bootstrap) here: http://www.dropzonejs.com/bootstrap.html
I do not use any forms. I got a view handling the in coming ajax posts from dropzone. Here is the gist of my view code:
class AjaxUploadView(View):
"""
View for uploading via AJAX.
"""
def post_ajax(self, request, *args, **kwargs):
uploaded_file = request.FILES['file']
# Do stuff with file
# Return appropriate response
Hope it helps.
Related
Good Afternoon,
I have a query when trying to create an edit template, I'm retrieving data via an api call. When I input the data in the django form.Forms the attachment is showing as blank.
This is the Form.py file
class PaymentListForm(forms.Form):
Title = forms.CharField(max_length=50)
Receipt_Amount = forms.DecimalField(max_digits=8, decimal_places=2)
Request_Amount = forms.DecimalField(max_digits=8, decimal_places=2)
Receipt_Attachment = forms.FileField()
def __init__(self, *args, **kwargs):
super(PaymentListForm, self).__init__(*args, **kwargs)
And this is the views.py file
def edit_payments(request, trn_pk):
trns = get_transaction_by_id(trn_pk)
data = trns['data']
if request.method == 'GET':
form = PaymentListForm(initial=data)
return render(request, 'paymentlist/createeditpayments.html', {'form': form})
I can confirm that in the data dictionary there is the link for the attachment but somehow in the forms the attachment is getting lost.
Any help reg this?
Thanks
There is no possibility to set initial value for FileField like in CharField or DecimalField but there is a way to solve this problem. What we need is to hide forms.FileField and handle loading files by a label and show initial data as just text. so first hide forms.FileField:
forms.py:
class PaymentListForm(forms.Form):
Title = forms.CharField(max_length=50)
Receipt_Amount = forms.DecimalField(max_digits=8, decimal_places=2)
Request_Amount = forms.DecimalField(max_digits=8, decimal_places=2)
Receipt_Attachment = forms.FileField(label="", widget=forms.FileInput(
attrs={'style': "display: none",},
), )
def __init__(self, *args, **kwargs):
super(PaymentListForm, self).__init__(*args, **kwargs)
now we need to add tag to handle uploading files instead forms.FileField and tag where we'll display info about attachment url. I'm not sure how html template looks exactly so i've made some generic one - important tag we need to place inside tag.
createeditpayments.html:
<form method="POST" action="" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<span>Receipt attachment: </span>
<label for="id_Receipt_Attachment" class="mt-2 btn btn-primary " style="cursor: pointer;">Choose file...</label>
<span id="receipt_url"> {{ url_of_receipt }}</span>
<br><br>
<button class="btn btn-primary" role="button" type="submit">
Save
</button>
so we should get such output:
of course u can style label, span as u want to. now we need to change a bit the view - specially to add to context dictionary url_of_receipt.
views.py:
def edit_payments(request, trn_pk):
trns = get_transaction_by_id(trn_pk)
data = trns['data']
if request.method == 'GET':
form = PaymentListForm(initial=data)
return render(request, 'paymentlist/createeditpayments.html', {'form': form, 'url_of_receipt': data['Receipt_Attachment']})
i've assumed that data is a dictionary with such structure:
data = {
'Title': 'Example title',
'Receipt_Amount': 21.99,
'Request_Amount': 34,
'Receipt_Attachment': 'media/example.receipt.pdf'
}
so now we've got such output:
and very last thing is to switch on uploading files after clicking the label. think the best way is to use jQuery and short script. so i the bottom of createeditpayments.html place such code:
createeditpayments.html
{% block javascript %}
<script>
// fetch url from hidden FieldField and insert it next to upload button
$("#id_Receipt_Attachment").change(function () {
{#readURL(this);#}
$('#receipt_url').text(' ' + this.files[0].name);
});
</script>
{% endblock %}
and in base.html (or any html which createeditpayments.html extends) place just above closing tag:
base.html:
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.0/dist/umd/popper.min.js"
integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
crossorigin="anonymous"></script>
{% block javascript %}{% endblock %}
</body>
now the label should upload files and change url next to it.
I am new to Django, I am trying to take input from user using html generated text field and not use django forms.
<form action="" method="post">
{ % csrf_token % }
<label for="name">Enter name: </label>
<input id="namefield" type="text" name="name_field" value="Default name">
<input type="submit" value="OK">
</form>
I want to save the name to my database, without creating a django form and taking in data from the form and saving it in the database via views.py file.
In your view:
If request.method == 'POST' :
name = request.POST['field_name']
#now you can save them into related model
MyModel.objects.create(username=name,other fields goes here)
You must create in the views.py file a method in which the templates and the logic of it, an example can be the following
#csrf_exempt
def home(request):
if request.method == 'POST':
var1 = request.POST.get('var1')
var2 = request.POST.get('var2')
var3 = request.POST.get('var3')
#Save to the database here
return render_to_response(
'home.html',
{'message': 'Update Success', }
)
else:
return render_to_response(
'home.html',
{}
)
Actually i need to get base64 image data generated by croppie javascript library. The image data look like below.
data:image/png;base64,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
Here is my HTML
<form action="{% url 'profile' %}" enctype="multipart/form-data" method="post" class="pic-upload-form" id="form">{% csrf_token %}
<div class="custom-file">
{% bootstrap_form form %}
</div>
<!-- Croppie area -->
<div id="upload-demo"></div>
<input type="hidden" id="image-data" name="imagebase64">
<button type="button" class="btn btn-outline-info btn-custom upload-result">save</button>
</form>
The last portion of my js where i bind the image data to a hidden input.
$('.upload-result').on('click', function (ev) {
$uploadCrop.croppie('result', {
type: 'base64',
size: 'viewport'
}).then(function (src) {
console.log(src);
// bind the image data to the hidden inpu id image-data
$('#image-data').attr('src', src);
$('#form').submit();
});
});
And here is my view
def user_profile_view(request):
'''Handle the image of the user.'''
if request.method == 'POST':
form = UploadPicForm(request.POST, request.FILES)
if form.is_valid():
profile = form.save(commit=False)
# get the base64 image data
profile.image = request.FILES['imagebase64']
profile.save()
messages.success(request, 'your pic updated successfully.')
return HttpResponseRedirect(reverse('learning_path_tracker:home'))
else:
# form's user field populated by current user
form = UploadPicForm(initial={'user': request.user})
return render(request, 'users/uploadpic.html', {'form': form})
I think the image data is not a string that's why request.FILES raise error. But how can i solve this, thanks in advance.
request.FILES only contain the files uploaded using input type="file". Whereas you're sending the image data as a base64 using type="hidden" which sends data as string, not as file.
So, the image should be present in request.POST instead of request.FILES.
Do this:
profile.image = request.POST['imagebase64']
As a side note, instead of accessing keys directly from a dictionary, you should use the dict's get() method because it let's you provide a default value if the requested key is not present in the dictionary.
profile.image = request.POST.get('imagebase64', "default value")
I'm collecting data from form, processing data(right now I'm not) and displaying the result on the same HTML page from where the user submits the form.
Here is my views.py file:
def index(request):
template = 'predictor/index.html'
if request.method =='POST':
form = EvalForm(request.POST)
if form.is_valid():
text ='thank you for submitting form'
else:
text='something wrong.'
context: {
'text':text,
}
return render(request,template,context)
else:
form = EvalForm()
return render(request,template)
Here is my index.html file
<form method="POST" action="{% url 'predictor' %}">
{% csrf_token %}
//all input fields including submit button here
</form>
<div class="result">
{{ text }}
</div>
All other things like urls are configured properly.
What I'm doing wrong here?
You have typo in your code.
Should be context = {'text':text,} instead of context: {'text':text,}.
I have the below model;
class AudioFile(models.Model):
name = models.CharField(max_length=100, default='')
audio_file = models.FileField()
uploader = models.ForeignKey(User, default='')
def __unicode__(self):
return self.name
The below form;
class AudioFileForm(forms.ModelForm):
class Meta:
model = AudioFile
fields = ['name', 'audio_file']
def clean_audio_file(self):
audio = self.cleaned_data.get('audio_file',False)
if audio:
if audio._size > 5*1024*1024:
raise ValidationError("File too large ( > 5mb )")
if os.path.splitext(audio.name)[1] != ".mp3":
raise ValidationError("We only support mp3!")
return audio
else:
raise validationError("Couldn't read uploaded file")
As you can see there's some custom validations
Then I have the below html with the AudioFileForm passed as form;
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<form method="post" action="{% url 'actual_upload_audio' %}">
{% csrf_token %}
{{ form }}
<input type="submit" value="Upload"/>
</form>
</body>
</html>
Now I know how to save the object had it not been containing a FileField. I would do something like this;
form = AudioFileForm(request.POST)
if form.is_valid():
name = form.cleaned_data['name']
//Say it contained another field, foo
foo = form.cleaned_data['foo']
uploader = request.user //view requires login
audio_file = Audio_File.objects.create(name=name,
foo=foo,
uploader=uploader)
audio_file.save()
return HttpResponse("Success!")
But there being a FileField in question I donno how to handle this. I read Django's documentation but don't really get it. A much easier elaborate explanation would be lovely.
For a start I have MEDIA_ROOT = '/home/afzalsh/works/openradio/audio_files/' in my settings.py
Update
Thanks to #Rohan I now have <form method="post" action="{% url 'actual_upload_audio' %}" enctype="multipart/form-data"> instead of <form method="post" action="{% url 'actual_upload_audio' %}">
Also have the below view thanks to #dzejdzej;
form = AudioFileForm(request.POST, request.FILES)
if form.is_valid():
form.cleaned_data['uploader'] = request.user
form.save()
return HttpResponseRedirect(reverse('home_audio',kwargs={'pk':audio_file.pk}))
else:
return HttpResponse("Form Invalid!")
But Form Invalid! :/
Your form should have enctype="multipart/form-data" attribute so that it submits files.
<form method="post" action="{% url 'actual_upload_audio' %}"
enctype="multipart/form-data" >
...
</form>
Since you're using ModelForm, why not let Django handle saving the whole model?
from django.shortcuts import redirect
form = AudioFileForm(request.POST)
if form.is_valid():
form.cleaned_data['uploader'] = request.user //view requires login
form.save()
return redirect(success_url)
If you're using Django >=1.7, upload_to field is no longer required. However, I consider it a good practice.
https://docs.djangoproject.com/en/1.8/ref/models/fields/#django.db.models.FileField.upload_to
Also redirect user after successful POST to avoid issues with csrf.
you should mention the upload_to attribute as : audio_file = models.FileField(upload_to='uploads')
here 'uploads' is the name of the directory you would like to upload your files to.
As Rohan seaid, you must defile your form in template like this.
<form method="post" action="{% url 'actual_upload_audio' %}"
enctype="multipart/form-data" >
...
</form>
This allows you to send files with request to view. Now in view you must have something like this:
def my_view(request):
if request.method == 'POST':
my_form = MyForm(request.POST, request.FILES)
if my_form.is_valid():
my_form.save()
You can initial your form FileField and ImageField with request.FILES