Reputation: 2922
I have a database that tracks items.
Each item can have multiple images associated with it.
My models look like this:
class Item(models.Model):
name = ...
price = ...
description = ...
class ItemImage(models.Model):
item = models.ForeignKey("Item", on_delete=models.CASCADE, related_name="images")
Before trying to add the images field to each item, my views looked like this:
class ItemAdd(CreateView):
model = Item
fields = ['name', 'price', 'description']
...
class ItemEdit(UpdateView):
model = Item
fields = ['name', 'price', 'description']
...
In order to add an images field, I changed my views to say this:
class ItemAdd(CreateView):
model = Item
form_class = ItemEditForm
...
class ItemEdit(UpdateView):
model = Item
form_class = ItemEditForm
...
And created this form:
class ItemEditForm(forms.ModelForm):
images = forms.ImageField(required=False, widget=forms.ClearableFileInput(attrs={'multiple': True}))
class Meta:
model = Item
fields = ('name', 'price', 'description')
This adds the file input field to my templates, but doesn't actually do anything with the images the user chooses.
Django's documentation has some info on how to handle multiple file uploads here, which is where I got the above images field code, but the sample code doesn't appear to be aware of models at all. If the form being edited is in the CreateView, and the Item doesn't exist yet, I could create the ItemImage object in the post() code, but I have no Item to associate it with.
I must be missing something, because it seems like this should be relatively simple.
Upvotes: 0
Views: 317
Reputation: 4404
As sample code at the referenced link suggested: ...Then override the post method of your FormView...
- you need to add saving logic for images in your view.
For Class-Based CreateView
this is done in form_valid()
:
class ItemAdd(CreateView):
model = Item
form_class = ItemEditForm
...
def form_valid(self, form):
self.object = form.save() # create Item first
images = self.request.FILES.getlist('images')
for image in images:
self.object.images.create(image=image)
return HttpResponseRedirect(self.get_success_url())
For UpdateView
you may need a bit different saving logic for images.
And probably a preview of already present images.
Nice API-Doc on Class-Based Views
Upvotes: 1