开发者

How to bind an image to an edit form in Django?

开发者 https://www.devze.com 2023-02-04 03:14 出处:网络
I have the following Model: class Listing(models.Model): name = models.CharField(max_length=50, verbose_name=\"Title\")

I have the following Model:

class Listing(models.Model):
    name = models.CharField(max_length=50, verbose_name="Title")
    images = models.ManyToManyField('Image')

, with the ManyToM开发者_如何学运维anyField linking to this Image class:

class Image(models.Model):
    thumb = ImageField(upload_to='images/uploads/')
    number = models.PositiveSmallIntegerField()

and a corresponding ModelForm like so:

class ListingEditForm(ModelForm):
    image1 = ImageField(required=False, label="Photo 1")
    image2 = ImageField(required=False, label="Photo 2")
    image3 = ImageField(required=False, label="Photo 3")

    class Meta:
        model = Listing
        exclude = ('images')

The idea is to not limit the number of images that can be associated with a Listing in the backend, but at this time I only need 3 images in the form. Uploading the images works fine, but how would you go about binding the form to a Listing instance so that the images are not 'None' when one views the edit form?

Obviously, this alone won't work, because image1, image2 and image3 are only form fields, and not part of the model:

form = forms.ListingEditForm(instance=listing)

So adding a dictionary as the first parameter seems like the obvious thing to do:

form = forms.ListingEditForm({'image1': ...},instance=listing)

but what should the value of that ... be? And how do I retrieve it from the Listing instance?


I'll answer my own question, even though it's not quite the answer I was looking for. I've looked around, and as far as I know, there is no reliable way in HTML to change the contents of a File input field. So, I could be wrong, but even if you send that information with the request, Django will have no way of showing the information in the field (since it doesn't correspond to a file on the local PC).

So, my solution is simply to send the urls of the images with the request, as one normally would:

return render_to_response('edit.html', {'image1': image1_url, ...})

Then, if this information is present, I use jQuery to place the images next to the file input field in the template, and update it if the user selects a new file. It's not the best, but it works.

I'll still be glad to hear any other solutions.


I would use foreign key relation in Image, and inlineformset_factory for generating the form.

ListingEditForm = inlineformset_factory(Listing, Image, max_num=3, extra=0)

I would also add image name field in Image model. That way user will have indication of uploaded files in form display, and he will also be able to delete images if he whishes so. If you need unlimited uploads you can simply change max_num to 0 and extra to 1.

Of course that way you cannot associate one image with more then one Listing object, but if you need user to be able to delete images that is not recommended anyway.

0

精彩评论

暂无评论...
验证码 换一张
取 消