Django's ModelMultipleChoiceField failing to add foreing keys ids
I'm trying to save a model from the Django's admin using forms:
Here are the models.py
:
class Availability(models.Model):
"""Model for the availability table."""
availability_id = models.AutoField(primary_key=True)
schedule = models.ForeignKey(
AdventureSchedule,
on_delete=models.CASCADE
)
available_guests = models.PositiveIntegerField(null=True, blank=True)
date = models.DateField(auto_now=False, auto_now_add=False)
price = models.DecimalField(max_digits=6, decimal_places=2, null=True)
discount = models.DecimalField(max_digits=6, decimal_places=2)
status = models.CharField(max_length=50, default='Available')
created = models.DateTimeField(auto_now_add=True)
last_updated = models.DateTimeField(auto_now=True)
class Meta:
"""Availability model Meta."""
verbose_name_plural = "2.3 - Availability"
def __str__(self):
return self.date.strftime("%B %d, %Y")
class Reservations(models.Model):
"""Model for the reservations table."""
reservation_id = models.AutoField(primary_key=True)
availability = models.ManyToManyField(Availability)
user = models.ForeignKey(BaseUser, on_delete=models.PROTECT)
num_guests = models.IntegerField()
num_military = models.IntegerField()
num_youth = models.IntegerField()
price = models.FloatField()
status = models.CharField(max_length=200)
created = models.DateTimeField(auto_now_add=True)
last_updated = models.DateTimeField(auto_now=True)
class Meta:
"""Reservations model Meta."""
verbose_name_plural = "Reservations"
The forms.py
:
class ReservationsAdminForm(forms.ModelForm):
"""ModelForm for the reservations model."""
class Meta:
model = Reservations
exclude = []
availability = forms.ModelMultipleChoiceField(
queryset=Availability.objects.all(),
required=False,
widget=FilteredSelectMultiple('availability', False)
)
def __init__(self, *args, **kwargs):
# Do the normal form initialisation.
super(ReservationsAdminForm, self).__init__(*args, **kwargs)
# If it is an existing reservation (saved objects have a pk).
if self.instance.pk:
# Populate the availability field with the current reservation.
self.fields['availability'].initial = self.instance.availability_set.all()
def save_m2m(self):
# Add the availability to the reservation.
self.instance.availability_set.set(self.cleaned_data['available_dates_select'])
def save(self, *args, **kwargs):
# Default save.
instance = super(ReservationsAdminForm, self).save()
# Save many-to-many data.
self.save_m2m()
return instance
And the admin.py
:
class ReservationsAdmin(admin.ModelAdmin):
# Use our custom form.
form = ReservationsAdminForm
So, the form does the job and displays the list on the admin page, I'm able to pick Availability
dates from the list, and fill in the rest of the fields. But, is failing at the moment I save it because it is not adding the foreign keys of the selected Availability
dates. Here's the error:
django.db.utils.IntegrityError: NOT NULL constraint failed: adventures_reservations.availability_id
Trying to debug the code at the save
function from the ReservationsAdminForm
, it seems like the cleaned_data
is as expected:
{'availability': <QuerySet [<Availability: December 24, 2022>, <Availability: December 23, 2022>]>, 'user': <BaseUser: user@email.com>, 'num_guests': 5, 'num_military': 1, 'num_youth': 1, 'price': 1.0, 'status': 'Reserved'}
After that point, it fails at the super(ReservationsAdminForm, self).save()
.
I'm not sure what I'm doing wrong. Thanks to anyone that can help me out.