1
0
mirror of https://github.com/django/django.git synced 2025-10-25 06:36:07 +00:00

Fixed #10243, #11043 -- Corrected handling of formsets over a ForeignKey that uses to_field, and by extension, fixed the admin for handling fields of that type. Thanks to apollo13 for the initial patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@10756 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Russell Keith-Magee
2009-05-13 14:04:29 +00:00
parent 96b5b6b34c
commit 7215ffe8a4
4 changed files with 50 additions and 4 deletions

View File

@@ -698,7 +698,11 @@ class BaseInlineFormSet(BaseModelFormSet):
self.save_as_new = save_as_new
# is there a better way to get the object descriptor?
self.rel_name = RelatedObject(self.fk.rel.to, self.model, self.fk).get_accessor_name()
qs = self.model._default_manager.filter(**{self.fk.name: self.instance})
if self.fk.rel.field_name == self.fk.rel.to._meta.pk.name:
backlink_value = self.instance
else:
backlink_value = getattr(self.instance, self.fk.rel.field_name)
qs = self.model._default_manager.filter(**{self.fk.name: backlink_value})
super(BaseInlineFormSet, self).__init__(data, files, prefix=prefix,
queryset=qs)
@@ -733,7 +737,7 @@ class BaseInlineFormSet(BaseModelFormSet):
# Use commit=False so we can assign the parent key afterwards, then
# save the object.
obj = form.save(commit=False)
setattr(obj, self.fk.get_attname(), self.instance.pk)
setattr(obj, self.fk.get_attname(), getattr(self.instance, self.fk.rel.field_name))
if commit:
obj.save()
# form.save_m2m() can be called via the formset later on if commit=False
@@ -749,6 +753,7 @@ class BaseInlineFormSet(BaseModelFormSet):
# The foreign key field might not be on the form, so we poke at the
# Model field to get the label, since we need that for error messages.
form.fields[self.fk.name] = InlineForeignKeyField(self.instance,
to_field=self.fk.rel.field_name,
label=getattr(form.fields.get(self.fk.name), 'label', capfirst(self.fk.verbose_name))
)
@@ -845,8 +850,12 @@ class InlineForeignKeyField(Field):
def __init__(self, parent_instance, *args, **kwargs):
self.parent_instance = parent_instance
self.pk_field = kwargs.pop("pk_field", False)
self.to_field = kwargs.pop("to_field", None)
if self.parent_instance is not None:
kwargs["initial"] = self.parent_instance.pk
if self.to_field:
kwargs["initial"] = getattr(self.parent_instance, self.to_field)
else:
kwargs["initial"] = self.parent_instance.pk
kwargs["required"] = False
kwargs["widget"] = InlineForeignKeyHiddenInput
super(InlineForeignKeyField, self).__init__(*args, **kwargs)
@@ -858,7 +867,11 @@ class InlineForeignKeyField(Field):
# 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):
if self.to_field:
orig = getattr(self.parent_instance, self.to_field)
else:
orig = self.parent_instance.pk
if force_unicode(value) != force_unicode(orig):
raise ValidationError(self.error_messages['invalid_choice'])
return self.parent_instance