summaryrefslogtreecommitdiff
path: root/django/forms/models.py
diff options
context:
space:
mode:
authorBrian Rosner <brosner@gmail.com>2008-10-31 22:09:56 +0000
committerBrian Rosner <brosner@gmail.com>2008-10-31 22:09:56 +0000
commit7b80af625bb20b7bbafa2224afdc8ee431428059 (patch)
treef6dea4a3e5523f0df1eb3258d332eed0d4c275c6 /django/forms/models.py
parent4931612727a1e3413b61879d24b27733a189d8b0 (diff)
[1.0.X] Fixed #8882 -- When a foreign key is among the unique_together fields in an inline formset properly handle it.
Backport of r9297 from trunk. git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.0.X@9298 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django/forms/models.py')
-rw-r--r--django/forms/models.py48
1 files changed, 40 insertions, 8 deletions
diff --git a/django/forms/models.py b/django/forms/models.py
index 0c98f52660..7f49324ff7 100644
--- a/django/forms/models.py
+++ b/django/forms/models.py
@@ -3,7 +3,7 @@ Helper functions for creating Form classes from Django models
and database field objects.
"""
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_unicode, force_unicode
from django.utils.datastructures import SortedDict
from django.utils.text import get_text_list, capfirst
from django.utils.translation import ugettext_lazy as _
@@ -468,7 +468,7 @@ class BaseInlineFormSet(BaseModelFormSet):
# creating new instances
form.data[form.add_prefix(self._pk_field.name)] = None
return form
-
+
def get_queryset(self):
"""
Returns this FormSet's queryset, but restricted to children of
@@ -485,7 +485,9 @@ class BaseInlineFormSet(BaseModelFormSet):
def add_fields(self, form, index):
super(BaseInlineFormSet, self).add_fields(form, index)
if self._pk_field == self.fk:
- form.fields[self._pk_field.name] = IntegerField(required=False, widget=HiddenInput)
+ form.fields[self._pk_field.name] = InlineForeignKeyField(self.instance, pk_field=True)
+ else:
+ form.fields[self.fk.name] = InlineForeignKeyField(self.instance, label=form.fields[self.fk.name].label)
def _get_foreign_key(parent_model, model, fk_name=None):
"""
@@ -537,11 +539,6 @@ def inlineformset_factory(parent_model, model, form=ModelForm,
# 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 = list(exclude)
- exclude.append(fk.name)
- else:
- exclude = [fk.name]
kwargs = {
'form': form,
'formfield_callback': formfield_callback,
@@ -560,6 +557,41 @@ def inlineformset_factory(parent_model, model, form=ModelForm,
# Fields #####################################################################
+class InlineForeignKeyHiddenInput(HiddenInput):
+ def _has_changed(self, initial, data):
+ return False
+
+class InlineForeignKeyField(Field):
+ """
+ A basic integer field that deals with validating the given value to a
+ given parent instance in an inline.
+ """
+ default_error_messages = {
+ 'invalid_choice': _(u'The inline foreign key did not match the parent instance primary key.'),
+ }
+
+ def __init__(self, parent_instance, *args, **kwargs):
+ self.parent_instance = parent_instance
+ self.pk_field = kwargs.pop("pk_field", False)
+ if self.parent_instance is not None:
+ kwargs["initial"] = self.parent_instance.pk
+ kwargs["required"] = False
+ kwargs["widget"] = InlineForeignKeyHiddenInput
+ super(InlineForeignKeyField, self).__init__(*args, **kwargs)
+
+ def clean(self, value):
+ if value in EMPTY_VALUES:
+ if self.pk_field:
+ return None
+ # if there is no value act as we did before.
+ return self.parent_instance
+ # ensure the we compare the values as equal types.
+ if force_unicode(value) != force_unicode(self.parent_instance.pk):
+ raise ValidationError(self.error_messages['invalid_choice'])
+ if self.pk_field:
+ return self.parent_instance.pk
+ return self.parent_instance
+
class ModelChoiceIterator(object):
def __init__(self, field):
self.field = field