Search code examples
djangodjango-modelsdjango-viewsdjango-forms

Change Model data after form submission in Django


Im writing a Booking System in Django with ModelForms, I Want to change value of a Boolean field in a ForeginKey model when form saves.

models.py

class AvailableHours(models.Model):
    free_date = models.ForeignKey(AvailableDates, null=True, blank=True,on_delete=models.CASCADE)
    free_hours_from = models.CharField(max_length=10,null=True, blank=True)
    free_hours_to = models.CharField(max_length=10,null=True, blank=True)
    status = models.BooleanField(null=True,default=True)

class Bookings(models.Model):   
...
    booked_time = models.ForeignKey(AvailableHours, on_delete=models.CASCADE,related_name='booked_time')
   

views.py

@login_required()
def booking_form(request):
    form = forms.BookingForm()
    if request.method == 'POST':
        form = forms.BookingForm(request.POST)
        if form.is_valid():
            book = form.save(commit=False)
            book.user = request.user
            form.save()
            return HttpResponseRedirect(reverse('creator:login'))
    return render(request, 'account/book.html', {'form': form})

forms.py

class BookingForm(forms.ModelForm):
    class Meta:
        model = Bookings
        exclude = ('user','booking_code','confirmed',)

Since I want each AvailableHours be able to get booked only once , I need the form to change value of AvailableHours status to False so I can filter it in templates.

Can anyone suggest an approach to this issue ?

I Tried something like

form.booked_time.status = False

in my views but it didnt work


Solution

  • you can use Django signals , it provide a convenient way to handle events.

    from django.db.models.signals import post_save
    from django.dispatch import receiver
    from .models import Bookings
    
    @receiver(post_save, sender=Bookings)
    def update_available_hours_status(sender, instance, created, **kwargs):
        if created:
            # If a new Booking is created
            booked_time = instance.booked_time
            booked_time.status = False
            booked_time.save()
    

    Reference