save form imagefield to another image field in view in django - python

I have the following view which saves one image field to another before saving:
if request.method == 'POST':
form = PlayerForm(request.POST, request.FILES, instance=current_player)
if form.is_valid():
temp_image = form.cleaned_data['profile_image2']
form.cleaned_data['profile_image'] = temp_image
form.profile_image = temp_image
form.save()
return redirect('player')
The problem is that the image does not save. I'm using boto as a backend. I'm not sure if this has anything to do with it.
How do I get the temp image to save to the profile image?

I think you might want to save the form to a model first and update profile_image after that:
from django.core.files.base import ContentFile
if form.is_valid():
new_player = form.save()
temp_image = new_player.profile_image2
# duplicate the image for "profile_image2"
dup_file = ContentFile(temp_image.read())
dup_file.name = temp_image.name
new_player.profile_image = dup_file
new_player.save()

Your code is a bit confusing to me. As I understood is that you're taking the image from profile_image2 and assigning it to profile_image field? If that is what you are trying then this would be a possible answer:
image = form['profile_image2']
photo = PlayerForm(profile_image=image)
photo.save()
[Beginner here so there might be a slight mistake, but that's how would I go about and solve this question, if I was doing what you are doing]

Related

Model field not updating in admin page even if value changes

I apologize for my confusing title but I hope the code explains it better.
In my views.py file I have the follow view
def create_view(request):
context = {}
form = CreateForm(request.POST)
if request.method == "POST":
if form.is_valid():
instance = form.save(commit=False)
instance.author = request.user
instance.save()
instance.author.profile.participating_in = Post.objects.get(
title=instance.title
)
instance.save()
print(instance.author.profile.participating_in)
context["form"] = form
return render(request, "post/post_form.html", context)
when I print out the value of instance.author.profile.participating_in it shows up in my terminal however when I check the admin page it doesnt update at all. I'm sure I messed up somewhere silly but I cant seem to find it. Thanks!
participating_in is the profile model field, but you are not calling the save() method for profile anywhere.
You have to do it like the following:
profile = instance.author.profile
profile.participating_in = Post.objects.get(title=instance.title)
profile.save()
If participating_in is ManyToManyField then we can do it like this:
post = Post.objects.get(title=instance.title)
instance.author.profile.participating_in.add(post)
Note that add(), create(), remove(), clear(), and set() all
apply database changes immediately for all types of related fields. In
other words, there is no need to call save() on either end of the
relationship.
Look at Related objects reference

Django form.is_valid returns false when a FileField is set to required

So I'm trying to make a form in Django with a FileField.
My forms.py looks like this:
from django import forms
class WordcloudForm(forms.Form):
matrix = forms.FileField(required=True)
min = forms.IntegerField(required=False)
max = forms.IntegerField(required=False)
# mask = forms.FileField(required=False)
I want the FileField to be a required field.
views.py:
def form(request):
if request.method == 'POST':
form = WordcloudForm(request.POST)
print(form.is_valid)
if form.is_valid():
if 'matrix' in request.FILES:
uploaded_matrix = request.FILES['matrix']
print(uploaded_matrix.name, uploaded_matrix.size)
min = form.cleaned_data['min']
max = form.cleaned_data['max']
print('min',min,'max',max)
print(form.errors)
When forms.FileField(required = True) in forms.py, form.is_valid() returns false:
When forms.FileField(required=False) in forms.py, form.is_valid() returns true:
When I submit the form with forms.FileField(required = True) my print(form.errors) states: "This field is required" even though I do add a file.
I tried different file formats to make sure the problem didn't just occur with the image I was using for testing.
What am I missing?
As mentioned in the documentation you need to pass request.FILES along with request.POST when initiating form instance:
if request.method == 'POST':
form = WordCloudForm(request.POST, request.FILES)
if form.is_valid():
# rest of the code
Also please rename your view method from form to anything meaningful, because you have a variable named form inside the method. Same with naming of variables min and max, they conflict with python's min and max functions. Your IDE is already marking them.

How to check if Django form contains any data?

I have Django function view with two forms inside. What is the best solution to detect which form has data typed by user? I know how form.is_valid() works, but still I want to check firstly which form was filled with data.
My code:
def edit_profile_view(request):
if request.method == "POST":
edit_form = EditProfileForm(request.POST)
pass_form = ChangePasswordForm(request.POST)
# here I want to detect which form has data inside,
# and then save this form
else:
edit_form = EditProfileForm()
pass_form = ChangePasswordForm()
template = get_template("profiles/profile_edit.html")
variables = RequestContext(request, {'edit_form': edit_form, 'pass_form': pass_form})
output = template.render(variables)
return HttpResponse(output)
Just have two different actions/views for the forms then the form that has data is the one that the user clicked submit on.
You could, like you say, just check what the form errors actually are or make a method on your forms for is_filled_in but this all seems overkill to me.

How can I let users upload images to photologue?

I've set up the Photologue, but I don't know how to let a (normal) user upload an image without using the admin interface.
I'd like to let users upload base64-encoded images from a HTML5 canvas, but in the first step it would be fine to upload files from the user's filesystem.
I guess I could modify this general example on how to upload files to use photologue's photo model. I assume this would mean somehow filling "ImageModel"'s ImageField attribute "image'.
I've actually used the linked file upload guide and adapted it to photologue. From my canvas element I extracted a base64 data url and set a form's field to its value then I could interpret it on Django's server side in a view:
def upload_base64(request):
# Handle file upload
if request.method == 'POST':
form = PhotoCodeForm(request.POST, request.FILES)
if form.is_valid():
uploaded_photo_data = base64.b64decode(request.POST['photocode'])
uploaded_photo_file = ContentFile(uploaded_photo_data)
title_str = "Untitled"
slug = slugify( title_str + str( datetime.now() ) )
uploaded_photo = Photo.objects.create( image = default_storage.save(slug, uploaded_photo_file),
title = slug,
title_slug = slug )
name_upload_gallery = "user-upload-queue"
try:
upload_gallery = Gallery.objects.get(title_slug__exact=name_upload_gallery)
except ObjectDoesNotExist:
return HttpResponseBadRequest('<html><body><p>The gallery "'+name_upload_gallery+'" does not exist.</p></body></html>')
upload_gallery.photos.add(uploaded_photo)
# Redirect to the photo gallery after POST
return HttpResponseRedirect('/canvas/')
else:
return HttpResponseBadRequest('<html><body><p>The entered data was not correct.</p></body></html>')
else:
form = PhotoCodeForm() # A empty, unbound form
return render_to_response(
'photologue_upload/upload_base64.html',
{'form': form},
context_instance=RequestContext(request)
)
upload_base64.html is a very simple form that has a field photocode where the base64 string is pasted to.

Django: Edit Function while not changing the Image data

I have an edit function that I want the user to be able to edit the Picture object (tags), while keeping the old image. The form is looking for a photo but I do want the user to be able to change the image - just the other information.
How do you pass the original image data from the picture object into the PictureForm so it validates?
My view:
#csrf_protect
#login_required
def edit_picture(request, picture_id, template_name="picture/newuserpicture.html"):
picture = get_object_or_404(Picture, id=picture_id)
if request.user != picture.user:
return HttpResponseForbidden()
if request.method == 'POST':
form = PictureForm(request.POST or None, request.FILES or None, instance=picture)
if form.is_valid():
form.save()
return HttpResponseRedirect('/picture/%d/' % picture.id )
else:
form = PictureForm(instance=picture)
data = { "picture":picture, "form":form }
return render_to_response(template_name,
data,
context_instance=RequestContext(request))
I think this thread should give you a clue how to make existing fields readonly:
In a Django form, how do I make a field readonly (or disabled) so that it cannot be edited?
I you want to hide the picture completely and stumble across validation errors because the field is marked as required in your model definition (blank=True) another option would be to override the form's save method and tweak the field's required attribute.
Something along these lines:
def __init__(self, *args, **kwargs):
super(PictureForm, self).__init__(*args, **kwargs)
for key in self.fields:
self.fields[key].required = False
I guess I am not sure how to just comment on the original question, but what do you mean by validate? If you are just needing to ensure that the picture object's picture is actually the same after the form is done can you not make some custom clean methods for the form? in a clean method you could compare all metadata and the image then proceed to the forms save.

Categories

Resources