Django

Code

Changeset 2313

Show
Ignore:
Timestamp:
02/17/06 06:46:03 (3 years ago)
Author:
russellm
Message:

magic-removal: Removed last references to OLD_get_accessor_name, and added unit tests to ensure accessor names are used correctly during validation.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/branches/magic-removal/django/core/management.py

    r2310 r2313  
    838838            dep_args = getattr(f, 'deprecated_args', None) 
    839839            if dep_args: 
    840                 e.add(opts, "'%s' field: Initialised with deprecated args:%s" % (f.name, ",".join(dep_args))) 
     840                e.add(opts, "'%s' Initialised with deprecated args:%s" % (f.name, ",".join(dep_args))) 
    841841            if isinstance(f, models.CharField) and f.maxlength in (None, 0): 
    842                 e.add(opts, '"%s" field: CharFields require a "maxlength" attribute.' % f.name) 
     842                e.add(opts, '"%s": CharFields require a "maxlength" attribute.' % f.name) 
    843843            if isinstance(f, models.FloatField): 
    844844                if f.decimal_places is None: 
    845                     e.add(opts, '"%s" field: FloatFields require a "decimal_places" attribute.' % f.name) 
     845                    e.add(opts, '"%s": FloatFields require a "decimal_places" attribute.' % f.name) 
    846846                if f.max_digits is None: 
    847                     e.add(opts, '"%s" field: FloatFields require a "max_digits" attribute.' % f.name) 
     847                    e.add(opts, '"%s": FloatFields require a "max_digits" attribute.' % f.name) 
    848848            if isinstance(f, models.FileField) and not f.upload_to: 
    849                 e.add(opts, '"%s" field: FileFields require an "upload_to" attribute.' % f.name) 
     849                e.add(opts, '"%s": FileFields require an "upload_to" attribute.' % f.name) 
    850850            if isinstance(f, models.ImageField): 
    851851                try: 
    852852                    from PIL import Image 
    853853                except ImportError: 
    854                     e.add(opts, '"%s" field: To use ImageFields, you need to install the Python Imaging Library. Get it at http://www.pythonware.com/products/pil/ .' % f.name) 
     854                    e.add(opts, '"%s": To use ImageFields, you need to install the Python Imaging Library. Get it at http://www.pythonware.com/products/pil/ .' % f.name) 
    855855            if f.prepopulate_from is not None and type(f.prepopulate_from) not in (list, tuple): 
    856                 e.add(opts, '"%s" field: prepopulate_from should be a list or tuple.' % f.name) 
     856                e.add(opts, '"%s": prepopulate_from should be a list or tuple.' % f.name) 
    857857            if f.choices: 
    858858                if not type(f.choices) in (tuple, list): 
    859                     e.add(opts, '"%s" field: "choices" should be either a tuple or list.' % f.name) 
     859                    e.add(opts, '"%s": "choices" should be either a tuple or list.' % f.name) 
    860860                else: 
    861861                    for c in f.choices: 
    862862                        if not type(c) in (tuple, list) or len(c) != 2: 
    863                             e.add(opts, '"%s" field: "choices" should be a sequence of two-tuples.' % f.name) 
     863                            e.add(opts, '"%s": "choices" should be a sequence of two-tuples.' % f.name) 
    864864            if f.db_index not in (None, True, False): 
    865                 e.add(opts, '"%s" field: "db_index" should be either None, True or False.' % f.name) 
     865                e.add(opts, '"%s": "db_index" should be either None, True or False.' % f.name) 
    866866 
    867867            # Check to see if the related field will clash with any 
     
    870870                rel_opts = f.rel.to._meta 
    871871                if f.rel.to not in models.get_models(): 
    872                      e.add(opts, "'%s' field: relates to uninstalled model %s" % (f.name, rel_opts.object_name)) 
    873                      
    874                 rel_name = RelatedObject(f.rel.to, cls, f).OLD_get_accessor_name() 
    875                 if rel_name in [r.name for r in rel_opts.fields]: 
    876                     e.add(opts, "'%s.%s' related field: Clashes with field on '%s.%s'" % (opts.object_name, f.name, rel_opts.object_name, rel_name)) 
    877                 elif rel_name in [r.name for r in rel_opts.many_to_many]: 
    878                     e.add(opts, "'%s.%s' related field: Clashes with m2m field on '%s.%s'" % (opts.object_name, f.name, rel_opts.object_name, rel_name)) 
    879                 elif rel_name in [r.OLD_get_accessor_name() for r in rel_opts.get_all_related_many_to_many_objects()]: 
    880                     e.add(opts, "'%s.%s' related field: Clashes with related m2m field '%s.%s'" % (opts.object_name, f.name, rel_opts.object_name, rel_name)) 
    881                 elif rel_name in [r.OLD_get_accessor_name() for r in rel_opts.get_all_related_objects() if r.field is not f]: 
    882                     e.add(opts, "'%s.%s' related field: Clashes with related field on '%s.%s'" % (opts.object_name, f.name, rel_opts.object_name, rel_name)) 
    883  
     872                     e.add(opts, "'%s' relates to uninstalled model %s" % (f.name, rel_opts.object_name)) 
     873                                     
     874                rel_name = RelatedObject(f.rel.to, cls, f).get_accessor_name() 
     875                for r in rel_opts.fields: 
     876                    if r.name == rel_name: 
     877                        e.add(opts, "'%s' accessor name '%s.%s' clashes with another field" % (f.name, rel_opts.object_name, r.name)) 
     878                for r in rel_opts.many_to_many: 
     879                    if r.name == rel_name: 
     880                        e.add(opts, "'%s' accessor name '%s.%s' clashes with a m2m field" % (f.name, rel_opts.object_name, r.name)) 
     881                for r in rel_opts.get_all_related_many_to_many_objects(): 
     882                    if r.get_accessor_name() == rel_name:                             
     883                        e.add(opts, "'%s' accessor name '%s.%s' clashes with a related m2m field" % (f.name, rel_opts.object_name, r.get_accessor_name())) 
     884                for r in rel_opts.get_all_related_objects(): 
     885                    if r.get_accessor_name() == rel_name and r.field is not f: 
     886                        e.add(opts, "'%s' accessor name '%s.%s' clashes with a related field" % (f.name, rel_opts.object_name, r.get_accessor_name())) 
     887                 
    884888        for i, f in enumerate(opts.many_to_many): 
    885889            # Check to see if the related m2m field will clash with any 
    886890            # existing fields, m2m fields, m2m related objects or related objects 
    887             if f.rel: 
    888                 rel_opts = f.rel.to._meta 
    889                 if f.rel.to not in models.get_models(): 
    890                     e.add(opts, "'%s' field: has m2m relation with uninstalled model %s" % (f.name, rel_opts.object_name)) 
    891  
    892                 rel_name = RelatedObject(f.rel.to, cls, f).OLD_get_accessor_name() 
    893                 if rel_name in [r.name for r in rel_opts.fields]: 
    894                     e.add(opts, "'%s.%s' related m2m field: Clashes with field on '%s.%s'" % (opts.object_name, f.name, rel_opts.object_name, rel_name)) 
    895                 elif rel_name in [r.name for r in rel_opts.many_to_many]: 
    896                     e.add(opts, "'%s.%s' related m2m field: Clashes with m2m field on '%s.%s'" % (opts.object_name, f.name, rel_opts.object_name, rel_name)) 
    897                 elif rel_name in [r.OLD_get_accessor_name() for r in rel_opts.get_all_related_many_to_many_objects() if r.field is not f]: 
    898                     e.add(opts, "'%s.%s' related m2m field: Clashes with related m2m field '%s.%s'" % (opts.object_name, f.name, rel_opts.object_name, rel_name)) 
    899                 elif rel_name in [r.OLD_get_accessor_name() for r in rel_opts.get_all_related_objects()]: 
    900                     e.add(opts, "'%s.%s' related m2m field: Clashes with related field on '%s.%s'" % (opts.object_name, f.name, rel_opts.object_name, rel_name)) 
     891            rel_opts = f.rel.to._meta 
     892            if f.rel.to not in models.get_models(): 
     893                e.add(opts, "'%s' has m2m relation with uninstalled model %s" % (f.name, rel_opts.object_name)) 
     894 
     895            rel_name = RelatedObject(f.rel.to, cls, f).get_accessor_name() 
     896            for r in rel_opts.fields: 
     897                if r.name == rel_name: 
     898                    e.add(opts, "'%s' m2m accessor name '%s.%s' clashes with another field" % (f.name, rel_opts.object_name, r.name)) 
     899            for r in rel_opts.many_to_many: 
     900                if r.name == rel_name: 
     901                    e.add(opts, "'%s' m2m accessor name '%s.%s' clashes with a m2m field" % (f.name, rel_opts.object_name, r.name)) 
     902            for r in rel_opts.get_all_related_many_to_many_objects(): 
     903                if r.get_accessor_name() == rel_name and r.field is not f:                             
     904                    e.add(opts, "'%s' m2m accessor name '%s.%s' clashes with a related m2m field" % (f.name, rel_opts.object_name, r.get_accessor_name())) 
     905            for r in rel_opts.get_all_related_objects(): 
     906                if r.get_accessor_name() == rel_name: 
     907                    e.add(opts, "'%s' m2m accessor name '%s.%s' clashes with a related field" % (f.name, rel_opts.object_name, r.get_accessor_name())) 
    901908 
    902909        # Check admin attribute. 
  • django/branches/magic-removal/django/db/models/query.py

    r2308 r2313  
    615615    """ 
    616616    if use_accessor: 
    617         matches = [f for f in field_list if f.OLD_get_accessor_name() == name] 
     617        matches = [f for f in field_list if (f.field.rel.related_name or f.opts.object_name.lower()) == name] 
    618618    else: 
    619619        matches = [f for f in field_list if f.name == name] 
  • django/branches/magic-removal/django/db/models/related.py

    r2263 r2313  
    7676        return self.field.rel.related_name or (self.opts.object_name.lower() + '_set') 
    7777 
    78     # TODO: Remove this. 
    79     def OLD_get_accessor_name(self): 
    80         rel_obj_name = self.field.rel.related_name or self.opts.object_name.lower() 
    81         if self.parent_model._meta.app_label != self.opts.app_label: 
    82             rel_obj_name = '%s_%s' % (self.opts.app_label, rel_obj_name) 
    83         return rel_obj_name 
  • django/branches/magic-removal/tests/modeltests/invalid_models/models.py

    r2310 r2313  
    1414    index = models.CharField(maxlength=10, db_index='bad')     
    1515 
     16class Target(models.Model): 
     17    tgt_safe = models.CharField(maxlength=10) 
     18     
     19    clash1_set = models.CharField(maxlength=10) 
     20     
     21class Clash1(models.Model): 
     22    src_safe = models.CharField(maxlength=10) 
     23     
     24    foreign = models.ForeignKey(Target) 
     25    m2m = models.ManyToManyField(Target) 
    1626 
    17 error_log = """invalid_models.fielderrors: "charfield" field: CharFields require a "maxlength" attribute. 
    18 invalid_models.fielderrors: "floatfield" field: FloatFields require a "decimal_places" attribute. 
    19 invalid_models.fielderrors: "floatfield" field: FloatFields require a "max_digits" attribute. 
    20 invalid_models.fielderrors: "filefield" field: FileFields require an "upload_to" attribute. 
    21 invalid_models.fielderrors: "prepopulate" field: prepopulate_from should be a list or tuple. 
    22 invalid_models.fielderrors: "choices" field: "choices" should be either a tuple or list. 
    23 invalid_models.fielderrors: "choices2" field: "choices" should be a sequence of two-tuples. 
    24 invalid_models.fielderrors: "choices2" field: "choices" should be a sequence of two-tuples. 
    25 invalid_models.fielderrors: "index" field: "db_index" should be either None, True or False. 
     27class Clash2(models.Model): 
     28    src_safe = models.CharField(maxlength=10) 
     29 
     30    foreign_1 = models.ForeignKey(Target, related_name='id') 
     31    foreign_2 = models.ForeignKey(Target, related_name='src_safe') 
     32 
     33    m2m_1 = models.ManyToManyField(Target, related_name='id') 
     34    m2m_2 = models.ManyToManyField(Target, related_name='src_safe') 
     35 
     36class Target2(models.Model): 
     37    foreign_tgt = models.ForeignKey(Target) 
     38    clashforeign_set = models.ForeignKey(Target) 
     39     
     40    m2m_tgt = models.ManyToManyField(Target) 
     41    clashm2m_set = models.ManyToManyField(Target) 
     42 
     43class Clash3(models.Model): 
     44    foreign_1 = models.ForeignKey(Target2, related_name='foreign_tgt') 
     45    foreign_2 = models.ForeignKey(Target2, related_name='m2m_tgt') 
     46     
     47    m2m_1 = models.ManyToManyField(Target2, related_name='foreign_tgt') 
     48    m2m_2 = models.ManyToManyField(Target2, related_name='m2m_tgt') 
     49     
     50class ClashForeign(models.Model): 
     51    foreign = models.ForeignKey(Target2) 
     52 
     53class ClashM2M(models.Model): 
     54    m2m = models.ManyToManyField(Target2) 
     55     
     56class SelfClashForeign(models.Model): 
     57    src_safe = models.CharField(maxlength=10) 
     58     
     59    selfclashforeign_set = models.ForeignKey("SelfClashForeign")  
     60    foreign_1 = models.ForeignKey("SelfClashForeign", related_name='id') 
     61    foreign_2 = models.ForeignKey("SelfClashForeign", related_name='src_safe') 
     62 
     63class SelfClashM2M(models.Model): 
     64    src_safe = models.CharField(maxlength=10) 
     65 
     66    selfclashm2m_set = models.ManyToManyField("SelfClashM2M") 
     67    m2m_1 = models.ManyToManyField("SelfClashM2M", related_name='id') 
     68    m2m_2 = models.ManyToManyField("SelfClashM2M", related_name='src_safe') 
     69 
     70error_log = """invalid_models.fielderrors: "charfield": CharFields require a "maxlength" attribute. 
     71invalid_models.fielderrors: "floatfield": FloatFields require a "decimal_places" attribute. 
     72invalid_models.fielderrors: "floatfield": FloatFields require a "max_digits" attribute. 
     73invalid_models.fielderrors: "filefield": FileFields require an "upload_to" attribute. 
     74invalid_models.fielderrors: "prepopulate": prepopulate_from should be a list or tuple. 
     75invalid_models.fielderrors: "choices": "choices" should be either a tuple or list. 
     76invalid_models.fielderrors: "choices2": "choices" should be a sequence of two-tuples. 
     77invalid_models.fielderrors: "choices2": "choices" should be a sequence of two-tuples. 
     78invalid_models.fielderrors: "index": "db_index" should be either None, True or False. 
     79invalid_models.clash1: 'foreign' accessor name 'Target.clash1_set' clashes with another field 
     80invalid_models.clash1: 'foreign' accessor name 'Target.clash1_set' clashes with a related m2m field 
     81invalid_models.clash1: 'm2m' m2m accessor name 'Target.clash1_set' clashes with another field 
     82invalid_models.clash1: 'm2m' m2m accessor name 'Target.clash1_set' clashes with a related field 
     83invalid_models.clash2: 'foreign_1' accessor name 'Target.id' clashes with another field 
     84invalid_models.clash2: 'foreign_1' accessor name 'Target.id' clashes with a related m2m field 
     85invalid_models.clash2: 'foreign_2' accessor name 'Target.src_safe' clashes with a related m2m field 
     86invalid_models.clash2: 'm2m_1' m2m accessor name 'Target.id' clashes with another field 
     87invalid_models.clash2: 'm2m_1' m2m accessor name 'Target.id' clashes with a related field 
     88invalid_models.clash2: 'm2m_2' m2m accessor name 'Target.src_safe' clashes with a related field 
     89invalid_models.clash3: 'foreign_1' accessor name 'Target2.foreign_tgt' clashes with another field 
     90invalid_models.clash3: 'foreign_1' accessor name 'Target2.foreign_tgt' clashes with a related m2m field 
     91invalid_models.clash3: 'foreign_2' accessor name 'Target2.m2m_tgt' clashes with a m2m field 
     92invalid_models.clash3: 'foreign_2' accessor name 'Target2.m2m_tgt' clashes with a related m2m field 
     93invalid_models.clash3: 'm2m_1' m2m accessor name 'Target2.foreign_tgt' clashes with another field 
     94invalid_models.clash3: 'm2m_1' m2m accessor name 'Target2.foreign_tgt' clashes with a related field 
     95invalid_models.clash3: 'm2m_2' m2m accessor name 'Target2.m2m_tgt' clashes with a m2m field 
     96invalid_models.clash3: 'm2m_2' m2m accessor name 'Target2.m2m_tgt' clashes with a related field 
     97invalid_models.clashforeign: 'foreign' accessor name 'Target2.clashforeign_set' clashes with another field 
     98invalid_models.clashm2m: 'm2m' m2m accessor name 'Target2.clashm2m_set' clashes with a m2m field 
     99invalid_models.target2: 'foreign_tgt' accessor name 'Target.target2_set' clashes with a related m2m field 
     100invalid_models.target2: 'foreign_tgt' accessor name 'Target.target2_set' clashes with a related m2m field 
     101invalid_models.target2: 'foreign_tgt' accessor name 'Target.target2_set' clashes with a related field 
     102invalid_models.target2: 'clashforeign_set' accessor name 'Target.target2_set' clashes with a related m2m field 
     103invalid_models.target2: 'clashforeign_set' accessor name 'Target.target2_set' clashes with a related m2m field 
     104invalid_models.target2: 'clashforeign_set' accessor name 'Target.target2_set' clashes with a related field 
     105invalid_models.target2: 'm2m_tgt' m2m accessor name 'Target.target2_set' clashes with a related m2m field 
     106invalid_models.target2: 'm2m_tgt' m2m accessor name 'Target.target2_set' clashes with a related field 
     107invalid_models.target2: 'm2m_tgt' m2m accessor name 'Target.target2_set' clashes with a related field 
     108invalid_models.target2: 'clashm2m_set' m2m accessor name 'Target.target2_set' clashes with a related m2m field 
     109invalid_models.target2: 'clashm2m_set' m2m accessor name 'Target.target2_set' clashes with a related field 
     110invalid_models.target2: 'clashm2m_set' m2m accessor name 'Target.target2_set' clashes with a related field 
     111invalid_models.selfclashforeign: 'selfclashforeign_set' accessor name 'SelfClashForeign.selfclashforeign_set' clashes with another field 
     112invalid_models.selfclashforeign: 'foreign_1' accessor name 'SelfClashForeign.id' clashes with another field 
     113invalid_models.selfclashforeign: 'foreign_2' accessor name 'SelfClashForeign.src_safe' clashes with another field 
     114invalid_models.selfclashm2m: 'selfclashm2m_set' m2m accessor name 'SelfClashM2M.selfclashm2m_set' clashes with a m2m field 
     115invalid_models.selfclashm2m: 'm2m_1' m2m accessor name 'SelfClashM2M.id' clashes with another field 
     116invalid_models.selfclashm2m: 'm2m_2' m2m accessor name 'SelfClashM2M.src_safe' clashes with another field 
    26117""" 
  • django/branches/magic-removal/tests/runtests.py

    r2310 r2313  
    172172                s.seek(0) 
    173173                error_log = s.read() 
    174                 expected = len(mod.error_log.split('\n')) - 1 
    175                 if error_log != mod.error_log: 
     174                actual = error_log.split('\n') 
     175                expected = mod.error_log.split('\n') 
     176                                     
     177                unexpected = [err for err in actual if err not in expected]     
     178                missing = [err for err in expected if err not in actual] 
     179                 
     180                if unexpected or missing: 
     181                    unexpected_log = '\n'.join(unexpected) 
     182                    missing_log = '\n'.join(missing) 
    176183                    log_error(model_name, 
    177                         "Validator found %d validation errors, %d expected" % (count, expected), 
    178                         "Expected errors:\n%s\n\nActual errors:\n%s" % (mod.error_log, error_log)) 
    179  
     184                        "Validator found %d validation errors, %d expected" % (count, len(expected) - 1), 
     185                        "Missing errors:\n%s\n\nUnexpected errors:\n%s" % (missing_log, unexpected_log)) 
    180186 
    181187        if run_othertests: