From d5119969012aa69b9b4ef345c7e0beb7d890509d Mon Sep 17 00:00:00 2001 From: Brian Rosner Date: Sun, 31 Aug 2008 21:14:46 +0000 Subject: [PATCH] Enforce max_num=1 on inline model formsets that have a unique foreign key to its parent. I snuck in a quick clean up to the inlineformset_factory as well. git-svn-id: http://code.djangoproject.com/svn/django/trunk@8775 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/forms/models.py | 22 +++++++++++++++------- tests/modeltests/model_formsets/models.py | 15 +++++++++++++++ 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/django/forms/models.py b/django/forms/models.py index 6acd32ce4f..4563ace3a2 100644 --- a/django/forms/models.py +++ b/django/forms/models.py @@ -424,17 +424,25 @@ def inlineformset_factory(parent_model, model, form=ModelForm, to ``parent_model``. """ fk = _get_foreign_key(parent_model, model, fk_name=fk_name) - # let the formset handle object deletion by default - + # enforce a max_num=1 when the foreign key to the parent model is unique. + if fk.unique: + max_num = 1 if exclude is not None: exclude.append(fk.name) else: exclude = [fk.name] - FormSet = modelformset_factory(model, form=form, - formfield_callback=formfield_callback, - formset=formset, - extra=extra, can_delete=can_delete, can_order=can_order, - fields=fields, exclude=exclude, max_num=max_num) + kwargs = { + 'form': form, + 'formfield_callback': formfield_callback, + 'formset': formset, + 'extra': extra, + 'can_delete': can_delete, + 'can_order': can_order, + 'fields': fields, + 'exclude': exclude, + 'max_num': max_num, + } + FormSet = modelformset_factory(model, **kwargs) FormSet.fk = fk return FormSet diff --git a/tests/modeltests/model_formsets/models.py b/tests/modeltests/model_formsets/models.py index b0ad420003..332c5a7235 100644 --- a/tests/modeltests/model_formsets/models.py +++ b/tests/modeltests/model_formsets/models.py @@ -54,6 +54,12 @@ class Owner(models.Model): def __unicode__(self): return "%s at %s" % (self.name, self.place) +class Location(models.Model): + place = models.ForeignKey(Place, unique=True) + # this is purely for testing the data doesn't matter here :) + lat = models.CharField(max_length=100) + lon = models.CharField(max_length=100) + class OwnerProfile(models.Model): owner = models.OneToOneField(Owner, primary_key=True) age = models.PositiveIntegerField() @@ -529,6 +535,15 @@ True >>> formset.save() [] +# ForeignKey with unique=True should enforce max_num=1 + +>>> FormSet = inlineformset_factory(Place, Location, can_delete=False) +>>> formset = FormSet(instance=place) +>>> for form in formset.forms: +... print form.as_p() +

+

+ # Foreign keys in parents ######################################## >>> from django.forms.models import _get_foreign_key