From 1b8b9686fa8b1ad6ee7f1b47cd3cfd59ab85049e Mon Sep 17 00:00:00 2001 From: Brian Rosner Date: Fri, 22 Aug 2008 19:27:26 +0000 Subject: [PATCH] Fixed #7947 -- Handle the display of OneToOneField in model forms correctly. Thanks tyson for the report and original patch. git-svn-id: http://code.djangoproject.com/svn/django/trunk@8469 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/contrib/admin/options.py | 5 ++++- django/db/models/fields/related.py | 6 +++++- tests/modeltests/model_forms/models.py | 20 ++++++++++++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index 8b9417bc3b..69fdb4f08e 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -128,7 +128,10 @@ class BaseModelAdmin(object): formfield = db_field.formfield(**kwargs) # Don't wrap raw_id fields. Their add function is in the popup window. if not db_field.name in self.raw_id_fields: - formfield.widget = widgets.RelatedFieldWidgetWrapper(formfield.widget, db_field.rel, self.admin_site) + # formfield can be None if it came from a OneToOneField with + # parent_link=True + if formfield is not None: + formfield.widget = widgets.RelatedFieldWidgetWrapper(formfield.widget, db_field.rel, self.admin_site) return formfield # For any other type of field, just call its formfield() method. diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index c8577ba22b..f5f27940b5 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -744,7 +744,6 @@ class OneToOneField(ForeignKey): """ def __init__(self, to, to_field=None, **kwargs): kwargs['unique'] = True - kwargs['editable'] = False if 'num_in_admin' not in kwargs: kwargs['num_in_admin'] = 0 super(OneToOneField, self).__init__(to, to_field, OneToOneRel, **kwargs) @@ -754,6 +753,11 @@ class OneToOneField(ForeignKey): SingleRelatedObjectDescriptor(related)) if not cls._meta.one_to_one_field: cls._meta.one_to_one_field = self + + def formfield(self, **kwargs): + if self.rel.parent_link: + return None + return super(OneToOneField, self).formfield(**kwargs) class ManyToManyField(RelatedField, Field): def __init__(self, to, **kwargs): diff --git a/tests/modeltests/model_forms/models.py b/tests/modeltests/model_forms/models.py index 56154f8a5b..c7e726ee4e 100644 --- a/tests/modeltests/model_forms/models.py +++ b/tests/modeltests/model_forms/models.py @@ -54,6 +54,12 @@ class Article(models.Model): def __unicode__(self): return self.headline +class ImprovedArticle(models.Model): + article = models.OneToOneField(Article) + +class ImprovedArticleWithParentLink(models.Model): + article = models.OneToOneField(Article, parent_link=True) + class PhoneNumber(models.Model): phone = models.PhoneNumberField() description = models.CharField(max_length=20) @@ -773,6 +779,20 @@ ValidationError: [u'Select a valid choice. 4 is not one of the available choices >>> list(f.choices) [(1L, 'multicategory Entertainment'), (2L, "multicategory It's a test"), (3L, 'multicategory Third'), (4L, 'multicategory Fourth')] +# OneToOneField ############################################################### + +>>> class ImprovedArticleForm(ModelForm): +... class Meta: +... model = ImprovedArticle +>>> ImprovedArticleForm.base_fields.keys() +['article'] + +>>> class ImprovedArticleWithParentLinkForm(ModelForm): +... class Meta: +... model = ImprovedArticleWithParentLink +>>> ImprovedArticleWithParentLinkForm.base_fields.keys() +[] + # PhoneNumberField ############################################################ >>> class PhoneNumberForm(ModelForm):