I am trying to combine Two models into one form. However I cannot save the form as it is not an instance of the models. What I'm after is a way to access the models as instances and then save. I am using crispy forms, I have described what I have tried at the bottom of the post, I have no idea why this is not working so as always any help is appreciated.
This is my model.py file:
from django.db import models
# Create your models here.
BOOKING_STATUS = ((0, 'To be confirmed'), (1, 'Confirmed'), (2, 'Declined'))
class Customer(models.Model):
first_name = models.CharField(max_length=80)
last_name = models.CharField(max_length=80)
email = models.EmailField()
phone_number = models.CharField(max_length=20)
def __str__(self):
return f"Customer {self.first_name + ' ' + self.last_name}"
class Booking(models.Model):
booking_date = models.DateField()
booking_time = models.TimeField()
number_attending = models.IntegerField(default=2)
booking_status = models.IntegerField(choices=BOOKING_STATUS, default=0)
customer = models.ForeignKey('Customer', on_delete=models.CASCADE)
def __str__(self):
return f"Booking by {self.customer}"
forms.py:
from .models import Customer, Booking
from django import forms
class CustomerForm(forms.ModelForm):
class Meta:
model = Customer
fields = '__all__'
class BookingForm(forms.ModelForm):
class Meta:
model = Booking
fields = ('booking_date', 'booking_time', 'number_attending')
class CustomerBookingForm(forms.Form):
customer_form = CustomerForm()
booking_form = BookingForm()
and my view.py
from django.shortcuts import render
from .forms import CustomerBookingForm
# Create your views here.
# https://stackoverflow.com/questions/51459435/django-create-multiple-instance-of-model-with-one-form
def customer_booking(request):
if request.method == 'POST':
customer_booking_form = CustomerBookingForm(request.POST)
# if customer_booking_form.is_valid():
else:
customer_booking_form = CustomerBookingForm()
context = {
'form': customer_booking_form,
}
return render(request, 'booking.html', context)
I have tried:
booking_instance = customer_booking_form.cleaned_data['booking_form'].save()
However this is not recognising the fields 'customer_form' or 'booking_form'
Instantiate both forms in your view, just add a prefix
argument to at least one of them.
def customer_booking(request):
if request.method == "POST":
customer_form = CustomerForm(request.POST, prefix="customer")
booking_form = BookingForm(request.POST, prefix="booking")
# if customer_form.is_valid()
# if booking_form.is_valid()
.....
else:
customer_form = CustomerForm(prefix="customer")
booking_form = BookingForm(prefix="booking")
The prefix
will let Django give each form a unique namespace. So, the field name
values will have the specified prefix for that ModelForm, i.e., customer-first_name
, booking-booking_time
, etc.