Ticket #8483: 8483-generic_fk_validations.diff

File 8483-generic_fk_validations.diff, 2.8 KB (added by Ramiro Morales, 10 years ago)

Ptahc that adds the validation for the reported user error and a couple of related ones

  • django/contrib/admin/validation.py

    diff -r 26c601aa95d3 django/contrib/admin/validation.py
    a b  
    88from django.forms.models import BaseModelForm, BaseModelFormSet, fields_for_model
    99from django.contrib.admin.options import flatten_fieldsets, BaseModelAdmin
    1010from django.contrib.admin.options import HORIZONTAL, VERTICAL
     11from django.contrib.contenttypes import generic
    1112
    1213__all__ = ['validate']
    1314
     
    149150                raise ImproperlyConfigured("'%s.inlines[%d].model' does not "
    150151                        "inherit from models.Model." % (cls.__name__, idx))
    151152            validate_base(inline, inline.model)
    152             validate_inline(inline)
     153            validate_inline(inline, model)
    153154
    154 def validate_inline(cls):
     155def validate_inline(cls, parent_model):
    155156    # model is already verified to exist and be a Model
    156157    if cls.fk_name: # default value is None
    157158        f = get_field(cls, cls.model, cls.model._meta, 'fk_name', cls.fk_name)
    158159        if not isinstance(f, models.ForeignKey):
    159160            raise ImproperlyConfigured("'%s.fk_name is not an instance of "
    160161                    "models.ForeignKey." % cls.__name__)
     162    elif issubclass(cls, generic.GenericInlineModelAdmin):
     163        # generic relationship inlines
     164        validate_generic_inline(cls, parent_model)
     165
    161166    # extra = 3
    162167    # max_num = 0
    163168    for attr in ('extra', 'max_num'):
     
    304309    except AttributeError:
    305310        raise ImproperlyConfigured("'%s.%s' refers to '%s' that is neither a field, method or property of model '%s'."
    306311            % (cls.__name__, label, field, model.__name__))
     312
     313def 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__))
Back to Top