Django

Code

Changeset 8442

Show
Ignore:
Timestamp:
08/19/08 09:17:24 (3 months ago)
Author:
russellm
Message:

Fixed #7908: Added validation checks on attempts to create ForeignKey? and M2M relations with abstract classes. Thanks to Rock Howard for the report.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/core/management/validation.py

    r8296 r8442  
    6969            if f.rel: 
    7070                if f.rel.to not in models.get_models(): 
    71                     e.add(opts, "'%s' has relation with model %s, which has not been installed" % (f.name, f.rel.to)) 
     71                    e.add(opts, "'%s' has a relation with model %s, which has either not been installed or is abstract." % (f.name, f.rel.to)) 
    7272                # it is a string and we could not find the model it refers to 
    7373                # so skip the next section 
     
    106106            # objects 
    107107            if f.rel.to not in models.get_models(): 
    108                 e.add(opts, "'%s' has m2m relation with model %s, which has not been installed" % (f.name, f.rel.to)) 
     108                e.add(opts, "'%s' has an m2m relation with model %s, which has either not been installed or is abstract." % (f.name, f.rel.to)) 
    109109                # it is a string and we could not find the model it refers to 
    110110                # so skip the next section 
  • django/trunk/django/db/models/fields/related.py

    r8415 r8442  
    647647            assert isinstance(to, basestring), "%s(%r) is invalid. First parameter to ForeignKey must be either a model, a model name, or the string %r" % (self.__class__.__name__, to, RECURSIVE_RELATIONSHIP_CONSTANT) 
    648648        else: 
     649            assert not to._meta.abstract, "%s cannot define a relation with abstract class %s" % (self.__class__.__name__, to._meta.object_name) 
    649650            to_field = to_field or to._meta.pk.name 
    650651        kwargs['verbose_name'] = kwargs.get('verbose_name', None) 
     
    757758class ManyToManyField(RelatedField, Field): 
    758759    def __init__(self, to, **kwargs): 
     760        try: 
     761            assert not to._meta.abstract, "%s cannot define a relation with abstract class %s" % (self.__class__.__name__, to._meta.object_name) 
     762        except AttributeError: # to._meta doesn't exist, so it must be RECURSIVE_RELATIONSHIP_CONSTANT 
     763            assert isinstance(to, basestring), "%s(%r) is invalid. First parameter to ManyToManyField must be either a model, a model name, or the string %r" % (self.__class__.__name__, to, RECURSIVE_RELATIONSHIP_CONSTANT) 
     764 
    759765        kwargs['verbose_name'] = kwargs.get('verbose_name', None) 
    760766        kwargs['rel'] = ManyToManyRel(to, 
  • django/trunk/tests/modeltests/invalid_models/models.py

    r8136 r8442  
    66 
    77from django.db import models 
    8 model_errors = "" 
     8 
    99class FieldErrors(models.Model): 
    1010    charfield = models.CharField() 
     
    169169    date_added = models.DateTimeField() 
    170170 
     171class AbstractModel(models.Model): 
     172    name = models.CharField(max_length=10) 
     173    class Meta: 
     174        abstract = True 
     175 
     176class AbstractRelationModel(models.Model): 
     177    fk1 = models.ForeignKey('AbstractModel') 
     178    fk2 = models.ManyToManyField('AbstractModel') 
     179     
    171180model_errors = """invalid_models.fielderrors: "charfield": CharFields require a "max_length" attribute. 
    172181invalid_models.fielderrors: "decimalfield": DecimalFields require a "decimal_places" attribute. 
     
    251260invalid_models.selfclashm2m: Reverse query name for m2m field 'm2m_3' clashes with field 'SelfClashM2M.selfclashm2m'. Add a related_name argument to the definition for 'm2m_3'. 
    252261invalid_models.selfclashm2m: Reverse query name for m2m field 'm2m_4' clashes with field 'SelfClashM2M.selfclashm2m'. Add a related_name argument to the definition for 'm2m_4'. 
    253 invalid_models.missingrelations: 'rel2' has m2m relation with model Rel2, which has not been installed 
    254 invalid_models.missingrelations: 'rel1' has relation with model Rel1, which has not been installed 
     262invalid_models.missingrelations: 'rel1' has a relation with model Rel1, which has either not been installed or is abstract. 
     263invalid_models.missingrelations: 'rel2' has an m2m relation with model Rel2, which has either not been installed or is abstract. 
    255264invalid_models.grouptwo: 'primary' has a manually-defined m2m relation through model Membership, which does not have foreign keys to Person and GroupTwo 
    256265invalid_models.grouptwo: 'secondary' has a manually-defined m2m relation through model MembershipMissingFK, which does not have foreign keys to Group and GroupTwo 
     
    261270invalid_models.personselfrefm2m: Intermediary model RelationshipTripleFK has more than two foreign keys to PersonSelfRefM2M, which is ambiguous and is not permitted. 
    262271invalid_models.personselfrefm2mexplicit: Many-to-many fields with intermediate tables cannot be symmetrical. 
     272invalid_models.abstractrelationmodel: 'fk1' has a relation with model AbstractModel, which has either not been installed or is abstract. 
     273invalid_models.abstractrelationmodel: 'fk2' has an m2m relation with model AbstractModel, which has either not been installed or is abstract. 
    263274"""