I've a django form for FileField
where I can input multiple files. I'm trying to send this list of files from django template to views using ajax.
But in my views I'm getting False
for form.is_valid
. Also, form.errors
shows:
file_form.errors <ul class="errorlist"><li>file<ul class="errorlist"><li>This fi
eld is required.</li></ul></li></ul>
I'm sure I'm not passing the data correctly through ajax. Do you have any idea where I'm going wrong?
My template:
<form id="file-form" enctype="multipart/form-data", method="POST">
{% csrf_token %}
<div id="id_file">{{ file_form }}</div>
<br><br>
<input type="submit" value="Upload files" name="_upload_file"/>
</form>
<script type="text/javascript">
$(document).on('submit', '#file-form', function(e)){
e.preventDefault();
$.ajax({
type:'POST',
url:'/create-post/',
data:{
files:$('#id_file').val(),
csrfmiddlewaretoken:$('input[name=csrfmiddlewaretoken]').val()
},
success:function(){
}
})
}
</script>
views.py
def upload_files(request): # create_to_feed
if request.method == 'POST':
if PostMediaModelForm(request.POST, request.FILES):
file_form = PostMediaModelForm(request.POST, request.FILES)
print("request.post", request.POST)
''' request.post <QueryDict: {'csrfmiddlewaretoken': ['CKsF77Sirdfgb72QG5oic86Wc0rHt
EIW7WYjw78tB9lDwOz5wwh1msdOymgGi9mh', 'CKsF77Sirdfgb72QG5oic86Wc0rHtEIW7WYjw78tB
9lDwOz5wwh1msdOymgGi9mh'], 'post_body': ['tests going on'], 'file': ['1.jpg', '2
.jpg', '3.jpg'], '_upload_file': ['Upload files']}> '''
print("request.FILES", request.FILES) # request.FILES <MultiValueDict: {}>
print("file_form.errors", file_form.errors) # shows the errors mentioned above
print("file form", file_form.data)
''' file form <QueryDict: {'csrfmiddlewaretoken': ['CKsF77Sirdfgb72QG5oic86Wc0rHtEIW
7WYjw78tB9lDwOz5wwh1msdOymgGi9mh', 'CKsF77Sirdfgb72QG5oic86Wc0rHtEIW7WYjw78tB9lD
wOz5wwh1msdOymgGi9mh'], 'post_body': ['tests going on'], 'file': ['1.jpg', '2.jp
g', '3.jpg'], '_upload_file': ['Upload files']}> '''
print("files are: ", file_form.data.getlist('file')) # files are: ['1.jpg', '2.jpg', '3.jpg']
print("file_form.is_valid()", file_form.is_valid(), "'_upload_file' in request.POST.data", '_upload_file' in request.POST)
# file_form.is_valid() False '_upload_file' in request.POST.data True
if '_upload_file' in request.POST:
files = request.FILES.getlist('file')
print("files: ", files) # files: []
print("no. of files: ", len(files)) # no. of files: 0
for f in files:
PostMedia.file = f
PostMedia.save(update_fields=["file"])
messages.success(request, 'File(s) uploaded!')
# return redirect('submit_post')
return HttpResponse('')
# else:
# return HttpResponse(str(file_form.errors))
elif PostModelForm(request.POST):
form = PostModelForm(request.POST)
if form.is_valid and '_create_post' in request.POST:
feed_instance = form.save(commit=False)
PostMedia.body = feed_instance
feed_instance.save()
PostMedia.save(update_fields=["body"])
messages.success(request, 'Your post was submitted successfully !')
return redirect('/create-post')
else:
form = PostModelForm()
file_form = PostMediaModelForm()
return render(request, 'multiuploads/form.html', {'form': form, 'file_form': file_form})
models.py
class Post(models.Model):
post_body = models.TextField(blank=False, max_length=500)
def __str__(self):
return str(self.post_body)
class PostMedia(models.Model):
file = models.FileField(blank=False, null=False, validators=[FileExtensionValidator(['jpg'])])
body = models.ForeignKey(Post, on_delete=models.CASCADE)
forms.py
class PostModelForm(ModelForm):
class Meta:
model = Post
fields = ['post_body']
class PostMediaModelForm(ModelForm):
class Meta:
model = PostMedia
fields = ['file']
widgets = {
'file': ClearableFileInput(attrs={'multiple': True}),
}
As you can see after clicking the upload button I should be able to save the form as in upload the files in the background while still staying on the same page and the once the I see file uploaded message I can be able to submit the whole form. Thanks in advance!