How to manage uploaded file in django - python

i want to manage(move and rename)files that user upload :
my upload form(html):
<form action="../valid_upload/" method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{form.as_p}}
<input type="submit" name="send" value="send" />
</form>
my form(django part):
class UploadImageForm(forms.Form):
image = forms.FileField()
name = forms.CharField(max_length=100)
about = forms.CharField(widget=forms.Textarea)
taq1 = forms.CharField(max_length=100)
taq2 = forms.CharField(max_length=100)
taq3 = forms.CharField(max_length=100)
url.py(just a one line):
url(r'valid_upload/', views.valid_upload, name='valid_upload'),
and view.py(just a part of that):
if 'username' in request.session:
if request.method == 'POST':
if 'image' in request.FILES:
form = UploadImageForm(request.POST, request.FILES)
if form.is_valid():
# Here goes the documentation code
return HttpResponse(request.FILES['image'].content_type)
//here i want to rename and move uploaded files
else:
return redirect('/upload_image')
else:
return redirect('/login/')
i want to know how to rename uploaded file and move them on my directories.if you can help me :)

You can pass the request data to your form, and let the form manage your needs. Here is an example:
if 'username' in request.session:
if request.method == 'POST':
if 'image' in request.FILES:
form = UploadImageForm(request.POST, request.FILES)
if form.is_valid():
# Here goes the documentation code
return HttpResponse(request.FILES['image'].content_type)
//here i want to rename and move uploaded files
else:
return redirect('/upload_image')
else:
return redirect('/login/')
You can use a django model too.
Here is the documentation:
https://docs.djangoproject.com/en/1.11/topics/http/file-uploads/

Related

Django: Why is the Image Field not working

Good day,
I am testing some stuff with Django image Fields and the user model. The point is simply that any user can upload and update a profile picture. But when I select a picture and press upload, I get the message 'This field is required. So it's as if I haven't selected anything.
\\photo.html
<form method="POST">
{% csrf_token %}
{{ form }}
<button type="submit">Upload</button>
</form>
\\views.py
def photo_view(request):
try:
profile = request.user.userimage
except UserImage.DoesNotExist:
profile = UserImage(user=request.user)
if request.method == 'POST':
form = UserImageForm(request.POST, instance=profile)
if form.is_valid():
form.save()
return redirect('/dashboard/user/profile')
else:
form = UserImageForm(instance=profile)
return render(request, 'photo.html', {'form': form})
\models.py
class UserImage(models.Model):
user = models.OneToOneField(
settings.AUTH_USER_MODEL, default=None, null=True, on_delete=models.CASCADE)
photo = models.ImageField(
upload_to='images/', height_field=None, width_field=None, max_length=100)
def __str__(self):
return str(self.user)
\\settings.py
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
I tried it with this one
https://www.geeksforgeeks.org/imagefield-django-models/
Do someone know a solution? Or should I even use the ImageField when working with images?
Thank you very much! :-)
There are two problems here: if you upload files, you need to specify enctype="multipart/form-data":
form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form }}
<button type="submit">Upload</button>
</form>
furthermore you need to pass both request.POST and request.FILES to the form:
def photo_view(request):
try:
profile = request.user.userimage
except UserImage.DoesNotExist:
profile = UserImage(user=request.user)
if request.method == 'POST':
form = UserImageForm(request.POST, request.FILES, instance=profile)
if form.is_valid():
form.save()
return redirect('/dashboard/user/profile')
else:
form = UserImageForm(instance=profile)
return render(request, 'photo.html', {'form': form})

unable to upload files in django through web forms

I am trying to create a django website similar to that of Udemy or Coursera. I am trying to implement a feature that lets users add courses.
Here is my view for adding the course:
def create_course(request):
form = CreateCourseForm()
if request.method == 'POST':
form = CreateCourseForm(request.POST)
if form.is_valid():
new_course = form.save(commit=False)
new_course.instructor = request.user
new_course.save()
return redirect('home')
return render(request, 'courses/create.html',{'form':form})
Here is my form:
class CreateCourseForm(forms.ModelForm):
class Meta:
model = Course
fields = ('name','video','description','category',)
My course model:
class Course(models.Model):
name = models.CharField(max_length=200)
instructor = models.ForeignKey(User, on_delete=models.CASCADE)
video = models.FileField(upload_to='videos/')
description = models.TextField()
category = models.ForeignKey(Category, on_delete=models.CASCADE)
def __str__(self):
return self.name
And finally my web form:
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<h1>Create a Course</h1>
<hr>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form|crispy }}
<button class="btn btn-sm btn-outline-primary" type="submit">Create Course</button>
</form>
{% endblock %}
The issue i am facing is that when i try to create a course, the video field shows an error "This field is required" even when I have uploaded a video.
I tried researching a bit and found out that adding enctype="multipart/form-data" to the form was required, but even adding that didn't solve my problem
Can anyone help me here?
You need to pass request.POST and request.FILES to the form, so:
def create_course(request):
form = CreateCourseForm()
if request.method == 'POST':
# add request.FILES &downarrow;
form = CreateCourseForm(request.POST, request.FILES)
# …
return render(request, 'courses/create.html',{'form':form})
If you only pass request.POST, you are only passing the items of the form that are not file uploads. This then will indeed add an error to the form fields of these files, saying that the form requires data for these fields.
as willem told you have to request file in you form like this
def create_course(request):
form = CreateCourseForm()
if request.method == 'POST':
form = CreateCourseForm(request.POST, request.FILES)
if form.is_valid():
new_course = form.save(commit=False)
new_course.instructor = request.user
new_course.save()
return redirect('home')
return render(request, 'courses/create.html',{'form':form})
but i think you have to know one more you don't have to pass / in while telling django where to upload that file
class Course(models.Model):
name = models.CharField(max_length=200)
instructor = models.ForeignKey(User, on_delete=models.CASCADE)
video = models.FileField(upload_to='videos')
description = models.TextField()
category = models.ForeignKey(Category, on_delete=models.CASCADE)
def __str__(self):
return self.name
offcourse willem answer will solve your problem but you will see in your media folder a new folder name videos/ got created where you file is storing instead of your actual folder becuase you are telling django to upload that file in folder name vedios/ and if django doesn't find that folder it will create that folder with that name and then stat uploading it

Error while uploading file through form in Django

I am trying to save a file and some other details in django using forms.
And I only want it to save a CharField and a FileField but not the country field.
For country field I want it to take its value through a post request.
But the form isn't saving. The errors says "data didn't validate".
Also this method works fine if I don't use a FileField.
models.py
class Simple(models.Model):
name = models.CharField(max_length=100)
city = models.FileField(upload_to='marksheet')
country = models.CharField(max_length=100)
forms.py
class SimpForm(forms.ModelForm):
class Meta:
model = Simple
fields = ['name','city']
A snippet from upload.html
<form action="upload" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<label>Test input</label>
<input type="text" name="country">
{{form.name}}
{{form.city}}
<button type="submit">Submit</button>
</form>
views.py
def upload(request):
if request.method == 'POST':
a = request.POST.get('country')
form = SimpForm(request.POST,request.FILES)
if form.is_valid():
post = form.save(commit=False)
post.country = a
post.save()
return HttpResponse('saved')
else:
return HttpResponse('ERROR SAVING')
else:
form = SimpForm()
return render(request,'upload.html',{'form':form})
You are not passing request.FILES in your form. You should pass it like this:
form = SimpForm(request.POST, request.FILES)
More information on file uploads can be found in documentation.

ImageField not accepting value from html file in DJANGO

I am making a custom CMS platform in Django. I want to upload a featured image from user.
Here is my forms.py
class CkEditorForm(ModelForm):
..........
..........
featuredImage = forms.ImageField(required=True)
My models.py
class Post(models.Model):
..........
..........
featuredImage = models.ImageField(upload_to="featured_image/")
My HTML Template
<div class="col-sm-6">
{{myForm.featuredImage}}
</div>
I used one more method in template but it didn't work for me-
<input type="file" name="featuredImage" accept="image/*" required id="id_featuredImage">
Note- Image is successfully uploaded via Django admin panel, But not working when I try to upload via Templates (HTML file)
Also, it was working when I use this method to render my form in html
{{myForm.as_p}}
But I want to render each form's input method as differently.
{{myForm.category}}
{{myForm.tags}}
{{myForm.featuredImage}}
Here is the views.py
def postView(request):
if request.method== "GET":
form = CkEditorForm()
return render(request,"post/post.html",{'myForm':CkEditorForm})
else:
if request.method == 'POST':
form = CkEditorForm(request.POST)
if form.is_valid():
form.save()
return render(request,"post/post.html",{'myForm':CkEditorForm})
else:
messages.error(request, "Error")
return render(request,"post/post.html",{'myForm':CkEditorForm})
I changed my Views.py and it worked for me...
def postView(request):
if request.method== "GET":
form = CkEditorForm()
return render(request,"post/post.html",{'myForm':CkEditorForm})
else:
if request.method == 'POST':
form = CkEditorForm(request.POST,request.FILES)
if form.is_valid():
form.save()
return render(request,"post/post.html",{'myForm':CkEditorForm})
else:
messages.error(request, "Error")
return render(request,"post/post.html",{'myForm':CkEditorForm})
I just change this. Add request.FILES to get image data.
form = CkEditorForm(request.POST,request.FILES)

Save Multiple Files from Django Forms to Model

Looking to upload 2 files into a Django Form using HTML5 (since it supports multi-file upload). The problem I'm facing is it's targets the 1st one for uploading. It knows there are 2 files, because when it saves, it saves twice (as per the for loop below). I thought to use the dictionary to loop over the names, but I receive an error that says this keyword can't be an expression. Maybe this is something simple, but if you need more, I can provide. Just a note, I did not use the forms.py for the file upload, but instead just the regular HTML <input tag. Thanks.
#page.html
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form_a.as_p }}
<input type="file" name="img" multiple>
<input type="submit" value="Submit" />
</form>
#models.py
def contact(request):
if request.method == 'POST':
form_a = RequestForm(request.POST, request.FILES)
if form_a.is_valid():
#assign form data to variables
saved_first_name = form_a.cleaned_data['First_Name']
saved_last_name = form_a.cleaned_data['Last_Name']
saved_department = form_a.cleaned_data['Department']
saved_attachments = request.FILES.getlist('img')
#create a dictionary representing the two Attachment Fields
tel = {'keyword1': 'Attachment_2', 'keyword1': 'Attachment_1'}
for a_file in saved_attachments:
#for every attachment that was uploaded, add each one to an Attachment Field
instance = Model(
Attachment_1=a_file,
Attachment_2=a_file
)
instance.save()
all_together_now = Model(First_Name=saved_first_name, Last_Name=saved_last_name,
Department=saved_department, Attachment_1=???, Attachment_2=???)
#save the entire form
all_together_now.save()
else:
#just return an empty form
form_a = RequestForm()
return render(request, 'vendor_db/contact.html', {'form_a': form_a})
Here is a way that worked for me. I loop each occurrence of an InMemoryUploadedFile in request.FILES and re-assign it back onto request.FILES, then save each one by one.
forms.py
class PhotosForm(forms.ModelForm):
file = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True}))
class Meta:
model = Photos
fields = ['file']
views.py
def photos(request):
photos = Photos.objects.all()
if request.method == 'GET':
form = PhotosForm(None)
elif request.method == 'POST':
for _file in request.FILES.getlist('file'):
request.FILES['file'] = _file
form = PhotosForm(request.POST, request.FILES)
if form.is_valid():
_new = form.save(commit=False)
_new.save()
form.save_m2m()
context = {'form': form, 'photos': photos}
return render(request, 'app/photos.html', context)

Categories

Resources