A
A
Alexander2016-04-21 00:12:05
Django
Alexander, 2016-04-21 00:12:05

How to save multiple images from a form to a model?

I have a declaration model:

class Advert(models.Model):
    category = models.TextField()
    title = models.CharField(max_length=64)
    description = models.CharField(max_length=900)
    photo = models.ImageField(upload_to='')
    date = models.DateTimeField(auto_now_add=True, null=True)

there is a form
class AddAdvertForm(ModelForm):
    class Meta:
        model = Advert
        fields = '__all__'

and a view that processes and saves the declaration
class CreateAdvertView(View):
    template_name = 'bulletinboard/add_advert.html'
    form_class = AddAdvertForm
    model = Advert

    def get(self, request):
        form = self.form_class()
        return render(request, self.template_name, {'form': form})

    def post(self, request):
        form = self.form_class(request.POST, request.FILES)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect('/')
        return render(request, self.template_name, {'form': form})

This view can only save one image which is submitted in the form, how do I save multiple images at a time?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
P
Pavel Aksenov, 2016-04-21
@AlexMine

It is impossible to save several shorts in one model (if there is only one field for pictures).
To save the pictures, you need to create a new model.
models.py

class Advert(models.Model):
    category = models.TextField()
    title = models.CharField(max_length=64)
    description = models.CharField(max_length=900)
    date = models.DateTimeField(auto_now_add=True, null=True)


class AdvertImage(models.Model):
    advert = models.ForeignKey(Advert)
    photo = models.ImageField(upload_to='uploads/')

forms.py
class AddAdvertForm(ModelForm):
    class Meta:
        model = Advert
        fields = '__all__'


class AdvertImagesForm(forms.Form):

    photos = forms.FileField(widget=widgets.FileInput(attrs={'multiple': True}))

    def __init__(self, *args, **kwargs):
        if 'request' in kwargs:
            self.request = kwargs.pop('request')
        super(AdvertImagesForm, self).__init__(*args, **kwargs)

    def clean_photos(self):
        # Остаются только картинки
        photos = [photo for photo in self.request.FILES.getlist('photos') if 'image' in photo.content_type]
        # Если среди загруженных файлов картинок нет, то исключение
        if len(photos) == 0:
            raise forms.ValidationError(u'Not found uploaded photos.')
        return photos

    def save_for(self, advert):
        for photo in self.cleaned_data['photos']:
            AdvertImage(photo=photo, advert=advert).save()

views.py
class CreateAdvertView(View):
    template_name = 'bulletinboard/add_advert.html'
    form_class = AddAdvertForm
    form_images_class = AdvertImagesForm
    model = Advert

    def get(self, request):
        form = self.form_class()
        form_images = self.form_images_class()
        return render(request, self.template_name, {'form': form, 'form_images': form_images})

    def post(self, request):
        form = self.form_class(request.POST)
        form_images = self.form_images_class(request.POST, request.FILES, request=request)
        if form.is_valid() and form_images.is_valid():
            advert = form.save()
            form_images.save_for(advert)
            return HttpResponseRedirect('/')
        return render(request, self.template_name, {'form': form, 'form_images': form_images})

I
Ilya, 2016-04-21
@FireGM

Create a separate model with ForeignKey on the Advert model.
Here is an example

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question