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.

Back to Top