Model & form setup for Multi model form(set)

The goal is to make a booking form, for the user (who represents a team) to select a meal option for each meal in one booking.
To do this, im using a MealBooking model:

class MealBooking(models.Model):
    team = models.ForeignKey("Organization.Team", on_delete=models.CASCADE)
    last_updated = models.DateTimeField(auto_now=True, editable=False)
    created = models.DateTimeField(auto_now_add=True, editable=False)
    status = models.CharField(max_length=100)

For each meal that the user need to pick a meal, I have created a Meal object via the meal model

class Meal(models.Model):
    meal_date = models.DateField()
    created = models.DateTimeField(auto_now_add=True, editable=False)
    last_updated = models.DateTimeField(auto_now=True, editable=False)
    name = models.CharField(max_length=100)

My idea is to use a TeamMeal object to track the choices.

class TeamMeal(models.Model):
    meal = models.ForeignKey("Butikken.MealPlan", on_delete=models.CASCADE)
    team = models.ForeignKey("Organization.Team", on_delete=models.CASCADE)
    meal_option = models.ForeignKey("Butikken.MealOption", on_delete=models.CASCADE)
    last_updated = models.DateTimeField(auto_now=True, editable=False)
    created = models.DateTimeField(auto_now_add=True, editable=False)

But im struggling to get the page to show the form.

the formset:

class TeamMealForm(forms.ModelForm):
    class Meta:
        model = models.TeamMeal
        fields = [
            "meal",
            "team",
            "meal_option",
        ]
        widgets = {
            "meal": forms.Select(attrs={"class": "form-control"}),
            "team": forms.Select(attrs={"class": "form-control"}),
            "meal_option": forms.Select(attrs={"class": "form-control"}),
        }

    def __init__(self, *args, **kwargs):
        super(TeamMealForm, self).__init__(*args, **kwargs)
        self.fields["meal"].queryset = Meal.objects.all()
        self.fields["team"].queryset = Team.objects.all()
        self.fields["meal_option"].queryset = MealOption.objects.all()

TeamMealFormSet = inlineformset_factory(MealBooking, TeamMeal, form=TeamMealForm, extra=0)

The html

<h1>Meal Booking for {{ booking.team.name }}</h1>
    <form method="post">
        {% csrf_token %}
        {{ formset.management_form }}
        <table>
            {% for form in formset %}
                <tr>
                    <td>{{ form.meal.label }}</td>
                    <td>{{ form.meal }}</td>
                    <td>{{ form.meal_option.label }}</td>
                    <td>{{ form.meal_option }}</td>
                </tr>
            {% endfor %}
        </table>
        <button type="submit">Save</button>
    </form>

the view

from .forms import TeamMealFormSet

def team_meal_booking_view(request, booking_id):
    booking = get_object_or_404(MealBooking, id=booking_id)
    
    if request.method == 'POST':
        formset = TeamMealFormSet(request.POST, instance=booking)
        if formset.is_valid():
            formset.save()
            return redirect('Butikken_MealBooking_list')  # Redirect to a success page
    else:
        formset = TeamMealFormSet(instance=booking)

    context = {
        'booking': booking,
        'formset': formset,
    }
    return render(request, 'mealbooking_form.html', context)

Have you tried setting a non-zero value on the extra attribute for the formset: like this:

TeamMealFormSet = inlineformset_factory(MealBooking, TeamMeal, form=TeamMealForm, extra=1)

When extra=0 and no TeamMeal currently exist in database for specified MealBooking the formset will be empty.
The extra attributes specifies how many empty form to add in formset for the creation of new instances of TeamMeal.

Is there any error? What it the javascript console output of your html?

Hi! thanks for the fast replies, and sorry for my late answer :slightly_smiling_face:

I have tried to change the formset to put an extra in the end

TeamMealPlanFormSet = inlineformset_factory(
    MealBooking, TeamMealPlan,
    form=forms.ModelForm,
    fields=['meal', 'meal_option'],
    extra=1,
    can_delete=True
)

I get no Javascript errors, and the management form does work correctly (the first part), but the TeamMealForm part is only partially working.

  1. So, your TeamMealPlan model is something like that?
class TeamMealPlan(models.Model):
    meal = models.ForeignKey(Meal, on_delete=models.CASCADE)
    meal_booking = models.ForeignKey(MealBooking, on_delete=models.CASCADE)
    meal_option = models.CharField(max_length=100)
  1. Your TeamPlanForm is something like that?
from django import forms
from django.forms import inlineformset_factory
from .models import MealBooking, TeamMealPlan

class TeamMealPlanForm(forms.ModelForm):
    class Meta:
        model = TeamMealPlan
        fields = ['meal', 'meal_option']

TeamMealPlanFormSet = inlineformset_factory(
    MealBooking, TeamMealPlan,
    form=TeamMealPlanForm,
    fields=['meal', 'meal_option'],
    extra=1,
    can_delete=True
)

Please provide all your models, forms, views, and templates in order to have a better understanding of your code.

Thanks! I tried to alter this, but without luck

Thanks for the response, I ended up going another direction. Sorry to take up your time :slight_smile: