Ticket #15932: 15932-1.4rc1-Fixed-model-validation-when-using-hidden-related_name.patch

File 15932-1.4rc1-Fixed-model-validation-when-using-hidden-related_name.patch, 3.2 KB (added by Clay McClure, 13 years ago)

Patch (with test) against 1.4rc1

  • django/core/management/validation.py

    From 393e4822ae3abf19115f4022d208df106b7cff85 Mon Sep 17 00:00:00 2001
    From: Clay McClure <clay@daemons.net>
    Date: Wed, 14 Mar 2012 15:41:48 -0400
    Subject: [PATCH] Fixed model validation when using hidden (+) related_names
     on M2M fields
    
    Fixes #15932.
    
    There is a comment in that same ticket about the ORM not working
    properly when hidden (+) related_names are used, but that could
    be tracked and fixed as a separate ticket. This commit fixes
    the validation issue originally reported.
    ---
     django/core/management/validation.py               |    6 +-----
     .../invalid_models/invalid_models/models.py        |   13 +++++++++++++
     2 files changed, 14 insertions(+), 5 deletions(-)
    
    diff --git a/django/core/management/validation.py b/django/core/management/validation.py
    index 4833337..3038382 100644
    a b def get_validation_errors(outfile, app=None):  
    244244            rel_opts = f.rel.to._meta
    245245            rel_name = RelatedObject(f.rel.to, cls, f).get_accessor_name()
    246246            rel_query_name = f.related_query_name()
    247             # If rel_name is none, there is no reverse accessor (this only
    248             # occurs for symmetrical m2m relations to self). If this is the
    249             # case, there are no clashes to check for this field, as there are
    250             # no reverse descriptors for this field.
    251             if rel_name is not None:
     247            if not f.rel.is_hidden():
    252248                for r in rel_opts.fields:
    253249                    if r.name == rel_name:
    254250                        e.add(opts, "Accessor for m2m field '%s' clashes with field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.name, f.name))
  • tests/modeltests/invalid_models/invalid_models/models.py

    diff --git a/tests/modeltests/invalid_models/invalid_models/models.py b/tests/modeltests/invalid_models/invalid_models/models.py
    index ed69fb6..b74f1da 100644
    a b class Target(models.Model):  
    3030    clash2 = models.CharField(max_length=10)
    3131
    3232    clash1_set = models.CharField(max_length=10)
     33    hiddenrelation_set = models.CharField(max_length=10)
    3334
    3435class Clash1(models.Model):
    3536    src_safe = models.CharField(max_length=10)
    class Clash2(models.Model):  
    4647    m2m_1 = models.ManyToManyField(Target, related_name='id')
    4748    m2m_2 = models.ManyToManyField(Target, related_name='src_safe')
    4849
     50class HiddenRelation(models.Model):
     51    "Hidden relations (related_name[-1] == '+') should not clash"
     52    foreign = models.ForeignKey(Target, related_name='+')
     53    m2m = models.ManyToManyField(Target, related_name='+')
     54   
     55class MultipleHiddenRelation(models.Model):
     56    "Multiple hidden relations (related_name[-1] == '+') should not clash with each other"
     57    foreign1 = models.ForeignKey(Target, related_name='+')
     58    foreign2 = models.ForeignKey(Target, related_name='+')
     59    m2m1 = models.ManyToManyField(Target, related_name='+')
     60    m2m2 = models.ManyToManyField(Target, related_name='+')
     61   
    4962class Target2(models.Model):
    5063    clash3 = models.CharField(max_length=10)
    5164    foreign_tgt = models.ForeignKey(Target)
Back to Top