Fixed #9932 -- Added a validation error when an inline tries to exclude the foreign key that provides the link to the parent model. Thanks to david for the report and patch.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@10668 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
80a54dd23b
commit
d7233e7c5a
|
@ -5,7 +5,7 @@ except NameError:
|
||||||
|
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.forms.models import BaseModelForm, BaseModelFormSet, fields_for_model
|
from django.forms.models import BaseModelForm, BaseModelFormSet, fields_for_model, _get_foreign_key
|
||||||
from django.contrib.admin.options import flatten_fieldsets, BaseModelAdmin
|
from django.contrib.admin.options import flatten_fieldsets, BaseModelAdmin
|
||||||
from django.contrib.admin.options import HORIZONTAL, VERTICAL
|
from django.contrib.admin.options import HORIZONTAL, VERTICAL
|
||||||
|
|
||||||
|
@ -146,9 +146,9 @@ def validate(cls, model):
|
||||||
raise ImproperlyConfigured("'%s.inlines[%d].model' does not "
|
raise ImproperlyConfigured("'%s.inlines[%d].model' does not "
|
||||||
"inherit from models.Model." % (cls.__name__, idx))
|
"inherit from models.Model." % (cls.__name__, idx))
|
||||||
validate_base(inline, inline.model)
|
validate_base(inline, inline.model)
|
||||||
validate_inline(inline)
|
validate_inline(inline, cls, model)
|
||||||
|
|
||||||
def validate_inline(cls):
|
def validate_inline(cls, parent, parent_model):
|
||||||
# model is already verified to exist and be a Model
|
# model is already verified to exist and be a Model
|
||||||
if cls.fk_name: # default value is None
|
if cls.fk_name: # default value is None
|
||||||
f = get_field(cls, cls.model, cls.model._meta, 'fk_name', cls.fk_name)
|
f = get_field(cls, cls.model, cls.model._meta, 'fk_name', cls.fk_name)
|
||||||
|
@ -167,6 +167,14 @@ def validate_inline(cls):
|
||||||
raise ImproperlyConfigured("'%s.formset' does not inherit from "
|
raise ImproperlyConfigured("'%s.formset' does not inherit from "
|
||||||
"BaseModelFormSet." % cls.__name__)
|
"BaseModelFormSet." % cls.__name__)
|
||||||
|
|
||||||
|
# exclude
|
||||||
|
if hasattr(cls, 'exclude') and cls.exclude:
|
||||||
|
fk_name = _get_foreign_key(parent_model, cls.model).name
|
||||||
|
if fk_name in cls.exclude:
|
||||||
|
raise ImproperlyConfigured("%s cannot exclude the field "
|
||||||
|
"'%s' - this is the foreign key to the parent model "
|
||||||
|
"%s." % (cls.__name__, fk_name, parent_model.__name__))
|
||||||
|
|
||||||
def validate_base(cls, model):
|
def validate_base(cls, model):
|
||||||
opts = model._meta
|
opts = model._meta
|
||||||
|
|
||||||
|
|
|
@ -4,12 +4,16 @@ Tests of ModelAdmin validation logic.
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
|
class Album(models.Model):
|
||||||
|
title = models.CharField(max_length=150)
|
||||||
|
|
||||||
class Song(models.Model):
|
class Song(models.Model):
|
||||||
title = models.CharField(max_length=150)
|
title = models.CharField(max_length=150)
|
||||||
|
album = models.ForeignKey(Album)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ('title',)
|
ordering = ('title',)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.title
|
return self.title
|
||||||
|
|
||||||
|
@ -19,9 +23,7 @@ __test__ = {'API_TESTS':"""
|
||||||
>>> from django.contrib import admin
|
>>> from django.contrib import admin
|
||||||
>>> from django.contrib.admin.validation import validate
|
>>> from django.contrib.admin.validation import validate
|
||||||
|
|
||||||
#
|
|
||||||
# Regression test for #8027: custom ModelForms with fields/fieldsets
|
# Regression test for #8027: custom ModelForms with fields/fieldsets
|
||||||
#
|
|
||||||
|
|
||||||
>>> class SongForm(forms.ModelForm):
|
>>> class SongForm(forms.ModelForm):
|
||||||
... pass
|
... pass
|
||||||
|
@ -40,4 +42,20 @@ Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
ImproperlyConfigured: 'InvalidFields.fields' refers to field 'spam' that is missing from the form.
|
ImproperlyConfigured: 'InvalidFields.fields' refers to field 'spam' that is missing from the form.
|
||||||
|
|
||||||
|
# Regression test for #9932 - exclude in InlineModelAdmin
|
||||||
|
# should not contain the ForeignKey field used in ModelAdmin.model
|
||||||
|
|
||||||
|
>>> class SongInline(admin.StackedInline):
|
||||||
|
... model = Song
|
||||||
|
... exclude = ['album']
|
||||||
|
|
||||||
|
>>> class AlbumAdmin(admin.ModelAdmin):
|
||||||
|
... model = Album
|
||||||
|
... inlines = [SongInline]
|
||||||
|
|
||||||
|
>>> validate(AlbumAdmin, Album)
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
ImproperlyConfigured: SongInline cannot exclude the field 'album' - this is the foreign key to the parent model Album.
|
||||||
|
|
||||||
"""}
|
"""}
|
||||||
|
|
Loading…
Reference in New Issue