From 1d485cf14ffa58dbeb130db2d50aa147556e0244 Mon Sep 17 00:00:00 2001 From: Jannis Leidel Date: Fri, 12 Aug 2011 14:15:08 +0000 Subject: [PATCH] Fixed #10405 -- Raise a more useful error if the formfield of a related model field can't be created yet because the related model isn't loaded yet. Thanks ojii and charstring. git-svn-id: http://code.djangoproject.com/svn/django/trunk@16604 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/core/exceptions.py | 2 +- django/db/models/fields/related.py | 4 +++ tests/regressiontests/forms/tests/models.py | 33 +++++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/django/core/exceptions.py b/django/core/exceptions.py index 21be8702fa..201a854a4b 100644 --- a/django/core/exceptions.py +++ b/django/core/exceptions.py @@ -3,7 +3,7 @@ Global Django exception and warning classes. """ class DjangoRuntimeWarning(RuntimeWarning): - pass + pass class ObjectDoesNotExist(Exception): "The requested object does not exist" diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index e7f4b9b3de..3e861cddd2 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -905,6 +905,10 @@ class ForeignKey(RelatedField, Field): def formfield(self, **kwargs): db = kwargs.pop('using', None) + if isinstance(self.rel.to, basestring): + raise ValueError("Cannot create form field for %r yet, because " + "its related model %r has not been loaded yet" % + (self.name, self.rel.to)) defaults = { 'form_class': forms.ModelChoiceField, 'queryset': self.rel.to._default_manager.using(db).complex_filter(self.rel.limit_choices_to), diff --git a/tests/regressiontests/forms/tests/models.py b/tests/regressiontests/forms/tests/models.py index 5e1bd82640..60fc4e83ba 100644 --- a/tests/regressiontests/forms/tests/models.py +++ b/tests/regressiontests/forms/tests/models.py @@ -1,7 +1,9 @@ # -*- coding: utf-8 -*- import datetime from django.core.files.uploadedfile import SimpleUploadedFile +from django.db import models from django.forms import Form, ModelForm, FileField, ModelChoiceField +from django.forms.models import ModelFormMetaclass from django.test import TestCase from regressiontests.forms.models import (ChoiceOptionModel, ChoiceFieldModel, FileModel, Group, BoundaryModel, Defaults) @@ -160,3 +162,34 @@ class FormsModelTestCase(TestCase): self.assertEqual(obj.name, u'class default value') self.assertEqual(obj.value, 99) self.assertEqual(obj.def_date, datetime.date(1999, 3, 2)) + +class RelatedModelFormTests(TestCase): + def test_invalid_loading_order(self): + """ + Test for issue 10405 + """ + class A(models.Model): + ref = models.ForeignKey("B") + + class Meta: + model=A + + self.assertRaises(ValueError, ModelFormMetaclass, 'Form', (ModelForm,), {'Meta': Meta}) + + class B(models.Model): + pass + + def test_valid_loading_order(self): + """ + Test for issue 10405 + """ + class A(models.Model): + ref = models.ForeignKey("B") + + class B(models.Model): + pass + + class Meta: + model=A + + self.assertTrue(issubclass(ModelFormMetaclass('Form', (ModelForm,), {'Meta': Meta}), ModelForm))