0

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))
Emile
  • 3,464
  • 8
  • 46
  • 77

2 Answers2

0

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.

grantk
  • 3,958
  • 4
  • 28
  • 37
  • Right now the form doesn't have an image file in the photo field. So when the function hits "form = PictureForm(request.POST or None, request.FILES or None, instance=picture)", it fails. The photo is required for the form. I'm not sure a clean method would do what I need- but I could be wrong. – Emile Mar 22 '11 at 16:40
  • can you post the error? If it is failing because the picture is None you should test that before instantiating the form. You could also try with a known id instead of your picture_id variable to make sure your passing in proper data. – grantk Mar 22 '11 at 16:47
  • "photo This field is required." Which is right. Because I am trying to keep the image the same, I do not want the user to upload a new image into the Picture object. I think I should be passing in the old image into ""form = PictureForm(request.POST or None, request.FILES or None, instance=picture)"" I thought instance=picture would work, but that isn't. – Emile Mar 22 '11 at 16:52
  • If your form only allows for editing of metadata like location, name, etc and those are the only form elements you should just be able to update those fields in the forms save, then call a picture.save() and the picture itself will be the same but with upated metadata. I think I am lost to as what you are asking for and the problem you are actually running into. If your form has a file upload widget just remove that widget, if you use the form elsewhere I would make a base form that does not include the upload widget that can be used for this edit view and inherit the base for the add form – grantk Mar 22 '11 at 17:01
  • Hmm like this? https://gist.github.com/881618 I think you are onto something, but the tags do not save from the form in that view. – Emile Mar 22 '11 at 17:26
  • depending on what you do in that save method yes. If you are not using the form elsewhere though just get rid of that file input. – grantk Mar 22 '11 at 17:56
0

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
Community
  • 1
  • 1
arie
  • 18,737
  • 5
  • 70
  • 76