I have a dialog that allows a user to create a new Cage object. In the same dialog, a user may also create new Mice that will automatically be assigned to that Cage (via a foreign_key field). I would like for it to be possible that multiple Mice can be created at the same time, using the same form if possible. I have previously implemented the singular version of this form (i.e. create one animal at a time). It would be nice to re-use this form:
#What's a good strategy for submitting multiple forms of the same type in a single view?
5 messages · Page 1 of 1 (latest)
class CreateMouseForm(forms.Form):
form_title = forms.CharField(initial = "CreateMouseForm", required = False)
birth_date = forms.DateField(help_text = "date of birth", label = "birthdate", initial = datetime.date.today())
mouse_id = forms.CharField(help_text = "", label = "mouse ID")
genotype = forms.CharField(help_text = "", label = "genotype")
sex = forms.ChoiceField(choices = Sex.choices)
cages: List[str] = []
for idx, c in enumerate(Cage.objects.all()):
cages.append((c.cage_id, c.cage_id)) # form.ChoiceField.choices expects tuple with contents (value, display)
cage = forms.ChoiceField(choices = cages)
# Magic Methods - called when self.cleaned_data[attr] is called
def clean_cage(self):
fk = Cage.objects.get(cage_id = self.cleaned_data['cage'])
return fk
I also created this helper function in views.py to handle the bound form:
def handleBoundCreateMouseForm(request: HttpRequest) -> None:
form: CreateMouseForm = CreateMouseForm(request.POST)
# change to try-except
if form.is_valid():
m: models.Mouse = models.Mouse()
m.birth_date = form.cleaned_data['birth_date']
m.fk_cage = form.cleaned_data['cage']
m.genotype = form.cleaned_data['genotype']
m.mouse_id = form.cleaned_data['mouse_id']
m.sex = form.cleaned_data['sex']
m.save()
else:
print("form invalid, ", form.errors)
Finally, here is the template that creates a Cage and Mice at once:
{% extends "generics/generic-dialog.html" %}
{% block dialog_content %}
{% load static %} <link rel = "stylesheet" href = "{% static 'css/components/cage-create-dialog.css' %}">
<form action="" method="POST">
{% csrf_token %}
<div class = "cage-create-dialog-container">
<div class = "cage-create-dialog-field">
{{ create_cage_form.form_title.as_hidden }}
<div>
Cage ID
</div>
<div>
{{ create_cage_form.cage_id }}
</div>
</div>
<div class = "cage-create-dialog-field">
<div>
Cage Type
</div>
<div>
{{ create_cage_form.cage_type }}
</div>
</div>
</div>
<div class = "cage-create-add-mouse">
<div class = "cage-create-dialog-field">
{{ create_mouse_form.form_title.as_hidden }}
<div>Mouse ID</div>
<div>{{ create_mouse_form.mouse_id }}</div>
</div>
<div class = "cage-create-dialog-field">
<div>Sex</div>
<div>{{ create_mouse_form.sex }}</div>
</div>
<div class = "cage-create-dialog-field">
<div>DOB</div>
<div>{{ create_mouse_form.birth_date }}</div>
</div>
<div class = "cage-create-dialog-field">
<div>Genotype</div>
<div>{{ create_mouse_form.genotype }}</div>
</div>
</div>
<input type = "submit" value = "Submit">
<input type = "button" value = "Cancel" onclick = "$(this).parents('dialog')[0].close()">
</form>
{% endblock dialog_content %}
Sounds like inline modelformset