Reputation: 121
I have 2 models
Tour to save Tour
TourImage to save images related to Tour
class Tour(models.Model):
name = models.CharField(max_length=50)
class TourImage(models.Model):
tour = models.ForeignKey(Tour, on_delete=models.CASCADE)
image = models.FileField(upload_to='images/')
In my views.py file I have the following code to save the Tour and the tour images
class CreateTourView(CreateView):
model = Tour
template_name = "create_tour.html"
fields = "__all__"
def form_valid(self, form):
tour = form.save()
for image in self.request.FILES.getlist("extra_images"):
TourImage.objects.create(tour=tour, image=image)
return super().form_valid(form)
The HTML form looks like this
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form | crispy }}
<input type="file" name="extra_images" multiple />
<input type="submit" value="Save" />
</form>
This works fine, the images are saved the Database.
But I also want to add option to edit Tour and add extra images, so the UpdateView code is as follows
class TourUpdateView(UpdateView):
model = Tour
template_name = "update_tour.html"
fields = "__all__"
def form_valid(self, form):
tour = form.save()
for image in self.request.FILES.getlist("extra_images"):
TourImage.objects.create(tour=tour, image=image)
return super().form_valid(form)
The .form_valid()
method is same for both CreateView and UpdateView.
Is there a better way to code this so as to avoid repetitive code?
Upvotes: 2
Views: 51
Reputation: 477240
You create a mixin:
class TourImageMixin:
model = Tour
def form_valid(self, form):
tour = form.save()
for image in self.request.FILES.getlist('extra_images'):
TourImage.objects.create(tour=tour, image=image)
return super().form_valid(form)
Then you mix it in the two views:
class CreateTourView(TourImageMixin, CreateView):
template_name = 'create_tour.html'
fields = '__all__'
class TourUpdateView(TourImageMixin, UpdateView):
template_name = "update_tour.html"
fields = '__all__'
In fact Django's views, like for example the ListView
[classy CBV] are constructed with mixins that define certain behavior. For the ListView
the MultipleObjectTemplateResponseMixin
[Django-doc], TemplateResponseMixin
[Django-doc] and MultipleObjectMixin
[Django-doc] are used.
Upvotes: 1