Commit d5119969 authored by Brian Rosner's avatar Brian Rosner
Browse files

Enforce max_num=1 on inline model formsets that have a unique foreign key to...

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
parent 4f5b0a32
Loading
Loading
Loading
Loading
+15 −7
Original line number Diff line number Diff line
@@ -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

+15 −0
Original line number Diff line number Diff line
@@ -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()
[<OwnerProfile: Joe Perry is 55>]

# 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()
<p><label for="id_location_set-0-lat">Lat:</label> <input id="id_location_set-0-lat" type="text" name="location_set-0-lat" maxlength="100" /></p>
<p><label for="id_location_set-0-lon">Lon:</label> <input id="id_location_set-0-lon" type="text" name="location_set-0-lon" maxlength="100" /><input type="hidden" name="location_set-0-id" id="id_location_set-0-id" /></p>

# Foreign keys in parents ########################################

>>> from django.forms.models import _get_foreign_key