Django ImageField: files dont get uploaded - python

I implemented some ImageFields in my model and installed PIL (not the cleanest install). Things seem to work as I get an upload button in the admin and when I call the .url property in the view I get the string with the filename + its upload property.
The problem is that the file is not there, apparently it doesnt get uploaded once I save the model.
Any idea?
Thanks
Here's a sample of my code situation
models.py
class My_Model(models.Model):
[...]
image = models.ImageField(upload_to = 'images/my_models/main')
view.py
'image': query.my_model.image.url
result:
static/images/my_models/main/theimage.png

Make sure that you're binding request.FILES to the form when POSTing, and that the form is declared as multi-part in the template
Here's the view from one of my applications:
#login_required
def submit(request):
if request.method == 'POST':
(Photo.objects.count()+1, request.FILES['photo'].name.split(".")[1]), request.FILES['photo'])}
form = PhotoForm(request.POST, request.FILES)
if form.is_valid():
new = Photo(photo=request.FILES['photo'], name=request.POST['name'])
new.save()
return HttpResponseRedirect('/') # Redirect after POST
else:
form = PhotoForm()
return render_to_response('app/submit.html', {'form': form}, context_instance=RequestContext(request))
and the PhotoForm class:
class PhotoForm(forms.ModelForm):
class Meta:
model = Photo
fields = ('name', 'photo')

Related

Poll is not saving

I am building a PollApp and I am stuck on a Problem..
I build a poll add feature for add images in the poll . BUT images are not adding in the Poll.
When i select images in field then save it redirect to the same page and saying "This field is required".
models.py
class ImageChoice(models.Model):
image_poll = models.ForeignKey(ImagePoll, on_delete=models.CASCADE)
choice_image = models.FileField()
views.py
def polls_add(request):
if request.method == 'POST':
form = ImagePollAddForm(request.POST)
if form.is_valid():
poll = form.save(commit=False)
poll.owner = request.user
poll.save()
new_choice1 = ImageChoice(poll=poll, image=form.cleaned_data['choice1']).save()
context = {
'form': form,
}
return render(request, 'add_poll.html', context)
forms.py
class ImagePollAddForm(forms.ModelForm):
choice1 = forms.FileField()
class Meta:
model = ImagePoll
fields = ['choice1']
When i try to upload images in each field then click to save then it is not uploading.
I also tried by adding request.FILES in form = ImagePollAddForm(request.POST) BUT it is showing ImageChoice() got an unexpected keyword argument 'poll' .
You use invalid field name, your model has image_poll field but not poll. And your model does not have image field but choice_image
ImageChoice(image_poll=poll, choice_image=form.cleaned_data['choice1']).save()

Forms and views for custom User model with extra parameters [django 2.1]

Im trying to create a form that would allow me to add a profile picture to the custom User object. I know that there is OneToOne method, although I want it to be stored directly in User.
You need to extend default User Model like this:
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
"""Add more fields to default user model."""
profile_pic = models.ImageField(upload_to='profile_pics', blank=True, null=True)
Now you need to edit your settings.py to make your custom User model the default auth model. Add this line in your settings.py:
AUTH_USER_MODEL = 'myApp.User'
myApp is the name of app in whose models.py your created your Custom User Model.
And that's all, now the default auth model is your custom model User which is exactly the same as the Django default auth model except it has an additional field profile_pic to store an image.
Form to add picture should be like this:
class profilepictureForm(forms.ModelForm):
"""Form to add profile picture to User model."""
class Meta:
"""Meta class for profilepictureForm."""
model = User
fields = ('profile_pic', )
And in your views you should use this form like this:
def add_profile_picture(request):
if request.method == 'POST':
form = profilepictureForm(request.POST, request.FILES, instance=request.user)
if form.is_valid():
form.save()
return HttpResponseRedirect('/success/url/')
else:
form = profilepictureForm(instance=request.user)
return render(request, 'userpanel/profilepicture.html', {'form': form})
Have a look on below code
from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import UploadFileForm
# Imaginary function to handle an uploaded file.
from somewhere import handle_uploaded_file
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(request, 'upload.html', {'form': form})
For more information please check https://docs.djangoproject.com/en/dev/topics/http/file-uploads/

Django, viewing uploaded files and videos

I would like to be able to view my uploaded files. I really have a poor grasp of what I am doing.
views.py
def upload_file(request):
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('learning_logs:topics'))
else:
form = DocumentForm()
return render(request, 'learning_logs/model_form_upload.html', {'form':form})
def file_preview(request):
videos = Document.objects.all()
context = {'videos':videos}
return render(request, 'learning_logs/video.html', context)
models.py
class Document(models.Model):
docfile = models.FileField(upload_to = 'documents/')
upload_at = models.DateTimeField(auto_now_add = True)
forms.py
class DocumentForm(forms.ModelForm):
class Meta:
model = Document
fields = ['docfile']
I have uploaded videos and pictures.
As the files are passed onto the HTML, I can only see the names of the files I uploaded. I can't click on the links and view the files.
I would like to have an actual video player to play the videos, or view the pictures.
Use url attribute of FileField in your template and pass that URL to your favorite player js library.

Django: Having trouble with users uploading files, and updating records in the db

For my django project, I am using a custom user model, and this works just fine. I also have a page that lets a user edit their own profile, and this also works correctly.
I just added an ImageField field to my user model for an avatar image. However I am having trouble with letting the user update the image themselves. It works fine in the admin interface, but not my user form.
Here is the relevant part models.py
# Generates the path for uploaded avatar images
def upload_avatar_path(instance, filename):
ext = filename.split('.')[-1]
return 'user/{0}/avatar.{1}'.format(instance.username, ext)
# Users
class User(AbstractBaseUser):
"""
Custom user model for amvl.
"""
username = models.CharField(
unique=True,
max_length=50,
)
avatar = models.ImageField(
upload_to=upload_avatar_path,
default='user/default.png'
)
bio = models.TextField()
class ProfileUpdateForm(forms.ModelForm):
class Meta:
model = User
fields = ['avatar', 'bio']
As you can see, the form am using for a user to edit their profile is a ModelForm.
Here is the views.py
def profile_edit(request, profile):
# Check if logged in user is the same as the profile edit page
if request.user.username == profile:
profile = User.objects.get(username=request.user.username)
# If this is a form submission
if request.method == 'POST':
form = ProfileUpdateForm(request.POST, request.FILES)
if form.is_valid():
try:
update = ProfileUpdateForm(
request.POST,
request.FILES,
instance=profile,
)
update.save()
return HttpResponse("UPDATED")
except:
return HttpResponse('FAILED')
else:
form = ProfileUpdateForm(instance=profile)
context = {
'form': form,
}
return render(request, 'user/profile_edit.html', context)
else:
return HttpResponse("NOT ALLOWED")
Everything works correctly here, except for updating the avatar field. Interestingly, when I submit the form "UPDATED" is returned, indicating that it worked. But when I check, the avatar image is not updated, even if other fields are.
Other examples I've seen seem to suggest that I need to use request.FILES['avatar'] to save the record, but when I do, it returns "FAILED".
When I remove the try and except statements to view the debug info, its shows a MultiValueDictKeyError at /user/admin/edit/, "'avatar'". (When I use request.FILES['avatar'])
According to the Django documentation for file uploads, and since you’re working with a ModelForm, you should use:
if request.method == 'POST':
form = ProfileUpdateForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return HttpResponseRedirect('/success/url/')
In case you’re not using a ModelForm…
…but you’re building one of your own, use:
if request.method == 'POST':
form = ProfileUpdateForm(request.POST, request.FILES)
if form.is_valid():
instance = User(avatar=request.FILES['avatar'])
instance.save()
return HttpResponseRedirect('/success/url/')
Now, if it still raises a MultiValueDictKeyError (I’m actually not sure of which to give to the key), try catching the exception to get the keys of request.FILES:
try:
instance = User(avatar=request.FILES['avatar'])
except MultiValueDictKeyError:
raise KeyError('Keys for `request.FILES` are {}'.format(request.FILES.keys()))
I've figured it out. It had nothing to do with my python code or Django, my HTML form was missing it's enctype="multipart/form-data" attribute.

ImageField and Django Wizard Form

I've created a wizard form that worked up until I added an ImageField.
When I got to submit the form with an image file chosen I get returned to the page saying the ImageField is required.
I've set up the MEDIA_ROOT and have that working.
Here are the snippets of code I think are in question:
models.py
# CreatePuzzleWizard forms
class uploadForm(forms.Form):
puzzle_image = forms.ImageField()
puzzle_name = forms.CharField(max_length=30, widget=forms.TextInput(attrs={'class':'form-control'}))
puzzle_description = forms.CharField(max_length=300, widget=forms.TextInput(attrs={'class':'form-control'}))
views.py
class CreatePuzzleWizard(SessionWizardView):
template_name = "create.html"
file_storage = FileSystemStorage(location=os.path.join(settings.MEDIA_ROOT, 'tmp'))
def done(self, form_list, **kwargs):
form_data = process_form_data(form_list)
return render('complete.html', {'form_list', form_list})
def process_form_data(form_list):
form_data = [form.cleaned_data for form in form_list]
# do stuff with form data
return form_data
I get this issue:
http://imgur.com/vFSuprr
I can't seem to find the problem on the internet. I'm using Django 1.6.1
The Django Docs specify that there is unfortunately a little work to do when binding an uploaded file to a form field:
https://docs.djangoproject.com/en/dev/ref/forms/api/#binding-uploaded-files-to-a-form

Categories