diff -r 26c601aa95d3 django/contrib/admin/validation.py
a
|
b
|
|
8 | 8 | from django.forms.models import BaseModelForm, BaseModelFormSet, fields_for_model |
9 | 9 | from django.contrib.admin.options import flatten_fieldsets, BaseModelAdmin |
10 | 10 | from django.contrib.admin.options import HORIZONTAL, VERTICAL |
| 11 | from django.contrib.contenttypes import generic |
11 | 12 | |
12 | 13 | __all__ = ['validate'] |
13 | 14 | |
… |
… |
|
149 | 150 | raise ImproperlyConfigured("'%s.inlines[%d].model' does not " |
150 | 151 | "inherit from models.Model." % (cls.__name__, idx)) |
151 | 152 | validate_base(inline, inline.model) |
152 | | validate_inline(inline) |
| 153 | validate_inline(inline, model) |
153 | 154 | |
154 | | def validate_inline(cls): |
| 155 | def validate_inline(cls, parent_model): |
155 | 156 | # model is already verified to exist and be a Model |
156 | 157 | if cls.fk_name: # default value is None |
157 | 158 | f = get_field(cls, cls.model, cls.model._meta, 'fk_name', cls.fk_name) |
158 | 159 | if not isinstance(f, models.ForeignKey): |
159 | 160 | raise ImproperlyConfigured("'%s.fk_name is not an instance of " |
160 | 161 | "models.ForeignKey." % cls.__name__) |
| 162 | elif issubclass(cls, generic.GenericInlineModelAdmin): |
| 163 | # generic relationship inlines |
| 164 | validate_generic_inline(cls, parent_model) |
| 165 | |
161 | 166 | # extra = 3 |
162 | 167 | # max_num = 0 |
163 | 168 | for attr in ('extra', 'max_num'): |
… |
… |
|
304 | 309 | except AttributeError: |
305 | 310 | raise ImproperlyConfigured("'%s.%s' refers to '%s' that is neither a field, method or property of model '%s'." |
306 | 311 | % (cls.__name__, label, field, model.__name__)) |
| 312 | |
| 313 | def validate_generic_inline(cls, parent_model): |
| 314 | opts = cls.model._meta |
| 315 | for f in opts.virtual_fields: |
| 316 | if isinstance(f, generic.GenericForeignKey): |
| 317 | break |
| 318 | else: |
| 319 | raise ImproperlyConfigured("'%s' is a generic inline, but the model " |
| 320 | "it is being associated with (%s) has no generic foreing key field." |
| 321 | % (cls.__name__, cls.model.__name__)) |
| 322 | for gr in opts.fields: |
| 323 | if gr.name == f.fk_field: |
| 324 | break |
| 325 | else: |
| 326 | raise ImproperlyConfigured("'%s' is a generic inline, but the model " |
| 327 | "it is being associated with (%s) has not a properly set up " |
| 328 | "fk_field field." % (cls.__name__, cls.model.__name__)) |
| 329 | |
| 330 | if gr.__class__ is not parent_model._meta.pk.__class__: |
| 331 | raise ImproperlyConfigured("Model %s associated with generic inline " |
| 332 | "'%s' has a %s field whose type doesn't match the type of " |
| 333 | "the primary key of the model it is being related to (%s)." |
| 334 | % (cls.model.__name__, cls.__name__, f.fk_field, |
| 335 | parent_model.__name__)) |