tags:

views:

154

answers:

2

I have a user profile model which holds their 'mugshot' image. I'm using modelForm to to present a profile update form. It was easy to build a working form, but now I need a couple of tweaks to the image:

1) it saves with the filename that the user provides; I rather dictate the filename to use. I thought I'd just use the PK of the model, and the same file extension eg: "443.jpg"

2) it should replace the existing image, not append an underscore. "443___.jpg".

class Member(models.Model):
    home_phone      = models.CharField(max_length=10, blank=True)
    image           = models.ImageField(upload_to='members', default="default.png")
...

class MemberProfileForm(forms.ModelForm):
    home_phone      = AUPhoneNumberField(required=False)

    class Meta:
        model = Member
        exclude = ('email','password','create_date','last_login','is_active')

I was hoping something like this would be all it takes:

    form = MemberProfileForm(request.POST, request.FILES, instance=request.member)
    if form.is_valid():
        if request.FILES.get("image"):
            form.image.name = 'poobar.jpg'
        form.save()
        return HttpResponseRedirect(reverse('my-profile'))

But 'image' doesn't exist in the modelform (AttributeError)

Do I need to rework the whole thing to use "form" instead of "modelform" just for these little tweaks, or is there an easy way to control the saving of the image?

x-----------------------------------------------------------------------------------------------

This seems to solve it...

    form = MemberProfileForm(request.POST, request.FILES, instance=request.member)
    if form.is_valid():
        if form.cleaned_data['image']:
            (path, extension) = os.path.splitext(form.cleaned_data['image'].name)
            form.cleaned_data['image'].name = ('%s%s' % (request.member.id, extension))
            request.member.image.delete()
        form.save()

... excepting that most people probably want 'request.user', where I have 'request.member'.

+2  A: 

By passing the instance kwarg to the form, it knows to overwrite the old data

form = MemberProfileForm(request.POST, request.FILES, instance=request.member)
if form.is_valid():
  form.save()

That is assuming request.member is a Member instance e.g.

profile=Member.objects.get(user=request.user)
form=MemberProfileForm(data=request.POST, files=request.FILES, instance=profile)
czarchaic
Thanks, but the question seeks to overcome a couple of issues with exactly what you describe. It does not overwrite the old image. See (1) and (2).
John Mee
A: 

There's a pretty good set of documentation on the official django website about how to handle file uploads and modify their location. That should answer your question about handling file upload locations.

Regarding image not being part of the form, it's located in the cleaned_data dictionary. You'll find it located at form.cleaned_data['image'].

Thomas
Oh, there we go, that's all that was wrong for (1). Thence, for (2), I can't see how to pass 'save=False' to the _image_ save routine which is inside modelform, but I can delete the existing image first which gets the same result. See the question for an edit showing the solution.
John Mee