'Django How to Upload an Image to Form
This is my code associated with the form:
# models
class Date(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
place = models.ForeignKey('Place', on_delete=models.CASCADE, null=True)
title = models.CharField(max_length=64, null=True)
class Photo(models.Model):
date = models.ForeignKey('Date', on_delete=models.CASCADE)
image = models.ImageField(verbose_name='Photos', upload_to='media/date/photos/')
# form
class DateForm(forms.ModelForm):
image = forms.ImageField()
class Meta:
model = Date
exclude = ('user',)
# view
class CreateDateView(LoginRequiredMixin, CreateView):
template_name = 'app/date/form.html'
form_class = DateForm
def form_valid(self, form):
form.instance.user = self.request.user
form.save() # by the way why do I save this form? Is it okay to save it in form_valid method?
photos = self.request.FILES.getlist('image')
for photo in photos:
Photo.objects.create(image=photo)
return super().form_valid(form)
The issue is how to save Photo objects if it requires a Date model id. It raises NOT NULL constraint failed: app_photo.date_id As I understand I have to write something like:
Photo.objects.create(date=date_from_the_form, image=photo)
But how to get the pk from the Date model? Hope you understand my problem, if any questions don't hesitate to write down below in comments section. Thanks in advance!
Solution 1:[1]
You need to create the date object first. Also, is each date going to be unique? If so, you need to change your model Meta declarations to include unique_together
.
You also need to avoid the for loop when creating each object. It's very expensive because it's going to make a round trip to the database for each save() called. That's what bulk_create
is for, which limits your database touches to one command to make many objects.
Here's pseudocode to get you going:
if len(photos) > 0: # don't create a date if there aren't photos
date = Date() # add your arguments
filtered = Date.objects.filter(date=date)
date = date.create() if not filtered.exists() else date = filtered[0] # but this is potentially dangerous if you risk duplicate dates. Only use this if you know it's the correct date
photos = [Photo(date=date,image=p) for p in photos]
Photo.objects.bulk_create(photos)
Good luck!
Solution 2:[2]
You need save the photo object:
def form_valid(self, form):
form.instance.user = self.request.user
form.save() # by the way why do I save this form? Is it okay to save it in form_valid method?
photos = self.request.FILES.getlist('image')
for photo in photos:
temp = Photo.objects.create(image=photo)
temp.save()
return super().form_valid(form)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Shaun Overton |
Solution 2 | LordPokerFace |