Ticket #683: 683_fix.patch

File 683_fix.patch, 29.0 KB (added by adrian, 9 years ago)

A patch that fixes it by introducing Field.attname

  • django/contrib/admin/views/main.py

     
    214214                        ((lookup_val is None and ' class="selected"' or ''),
    215215                        get_query_string(params, {}, [lookup_kwarg])))
    216216                    for val in lookup_choices:
    217                         pk_val = getattr(val, f.rel.to.pk.column)
     217                        pk_val = getattr(val, f.rel.to.pk.attname)
    218218                        filter_template.append('<li%s><a href="%s">%r</a></li>\n' % \
    219219                            ((lookup_val == str(pk_val) and ' class="selected"' or ''),
    220220                            get_query_string(params, {lookup_kwarg: pk_val}), val))
     
    378378                        capfirst(f.verbose_name)))
    379379        raw_template.append('</tr>\n</thead>\n')
    380380        # Result rows.
    381         pk = lookup_opts.pk.name
     381        pk = lookup_opts.pk.attname
    382382        for i, result in enumerate(result_list):
    383383            raw_template.append('<tr class="row%s">\n' % (i % 2 + 1))
    384384            for j, field_name in enumerate(lookup_opts.admin.list_display):
     
    393393                    except ObjectDoesNotExist:
    394394                        result_repr = EMPTY_CHANGELIST_VALUE
    395395                else:
    396                     field_val = getattr(result, f.column)
     396                    field_val = getattr(result, f.attname)
    397397                    # Foreign-key fields are special: Use the repr of the
    398398                    # related object.
    399399                    if isinstance(f.rel, meta.ManyToOne):
     
    785785                    new_data.setlist(f.name, new_data[f.name].split(","))
    786786            manipulator.do_html2python(new_data)
    787787            new_object = manipulator.save(new_data)
    788             pk_value = getattr(new_object, opts.pk.column)
     788            pk_value = getattr(new_object, opts.pk.attname)
    789789            log.log_action(request.user.id, opts.get_content_type_id(), pk_value, repr(new_object), log.ADDITION)
    790790            msg = 'The %s "%s" was added successfully.' % (opts.verbose_name, new_object)
    791791            # Here, we distinguish between different save types by checking for
     
    887887                    new_data.setlist(f.name, new_data[f.name].split(","))
    888888            manipulator.do_html2python(new_data)
    889889            new_object = manipulator.save(new_data)
    890             pk_value = getattr(new_object, opts.pk.column)
     890            pk_value = getattr(new_object, opts.pk.attname)
    891891
    892892            # Construct the change message.
    893893            change_message = []
     
    925925        new_data = {}
    926926        obj = manipulator.original_object
    927927        for f in opts.fields:
    928             new_data.update(_get_flattened_data(f, getattr(obj, f.column)))
     928            new_data.update(_get_flattened_data(f, getattr(obj, f.attname)))
    929929        for f in opts.many_to_many:
    930930            get_list_func = getattr(obj, 'get_%s_list' % f.rel.singular)
    931931            if f.rel.raw_id_admin:
    932                 new_data[f.name] = ",".join([str(getattr(i, f.rel.to.pk.column)) for i in get_list_func()])
     932                new_data[f.name] = ",".join([str(getattr(i, f.rel.to.pk.attname)) for i in get_list_func()])
    933933            elif not f.rel.edit_inline:
    934                 new_data[f.name] = [getattr(i, f.rel.to.pk.column) for i in get_list_func()]
     934                new_data[f.name] = [getattr(i, f.rel.to.pk.attname) for i in get_list_func()]
    935935        for rel_obj, rel_field in inline_related_objects:
    936936            var_name = rel_obj.object_name.lower()
    937937            for i, rel_instance in enumerate(getattr(obj, 'get_%s_list' % opts.get_rel_object_method_name(rel_obj, rel_field))()):
    938938                for f in rel_obj.fields:
    939939                    if f.editable and f != rel_field:
    940                         for k, v in _get_flattened_data(f, getattr(rel_instance, f.column)).items():
     940                        for k, v in _get_flattened_data(f, getattr(rel_instance, f.attname)).items():
    941941                            new_data['%s.%d.%s' % (var_name, i, k)] = v
    942942                for f in rel_obj.many_to_many:
    943943                    new_data['%s.%d.%s' % (var_name, i, f.column)] = [j.id for j in getattr(rel_instance, 'get_%s_list' % f.rel.singular)()]
     
    10261026                    # Display a link to the admin page.
    10271027                    nh(deleted_objects, current_depth, ['%s: <a href="../../../../%s/%s/%s/">%r</a>' % \
    10281028                        (capfirst(rel_opts.verbose_name), rel_opts.app_label, rel_opts.module_name,
    1029                         getattr(sub_obj, rel_opts.pk.column), sub_obj), []])
     1029                        getattr(sub_obj, rel_opts.pk.attname), sub_obj), []])
    10301030                _get_deleted_objects(deleted_objects, perms_needed, user, sub_obj, rel_opts, current_depth+2)
    10311031        else:
    10321032            has_related_objs = False
  • django/models/core.py

     
    4848        unique_together = (('package', 'python_module_name'),)
    4949
    5050    def __repr__(self):
    51         return "%s | %s" % (self.package, self.name)
     51        return "%s | %s" % (self.package_id, self.name)
    5252
    5353    def get_model_module(self):
    5454        "Returns the Python model module for accessing this type of content."
    55         return __import__('django.models.%s.%s' % (self.package, self.python_module_name), '', '', [''])
     55        return __import__('django.models.%s.%s' % (self.package_id, self.python_module_name), '', '', [''])
    5656
    5757    def get_object_for_this_type(self, **kwargs):
    5858        """
  • django/models/auth.py

     
    1313        ordering = ('package', 'codename')
    1414
    1515    def __repr__(self):
    16         return "%s | %s" % (self.package, self.name)
     16        return "%s | %s" % (self.package_id, self.name)
    1717
    1818class Group(meta.Model):
    1919    name = meta.CharField(_('name'), maxlength=80, unique=True)
     
    103103    def get_all_permissions(self):
    104104        if not hasattr(self, '_perm_cache'):
    105105            import sets
    106             self._perm_cache = sets.Set(["%s.%s" % (p.package, p.codename) for p in self.get_permission_list()])
     106            self._perm_cache = sets.Set(["%s.%s" % (p.package_id, p.codename) for p in self.get_permission_list()])
    107107            self._perm_cache.update(self.get_group_permissions())
    108108        return self._perm_cache
    109109
  • django/core/meta/__init__.py

     
    748748                except KeyError:
    749749                    try:
    750750                        # Object instance wasn't passed in -- must be an ID.
    751                         val = kwargs.pop(f.column)
     751                        val = kwargs.pop(f.attname)
    752752                    except KeyError:
    753753                        val = f.get_default()
    754754                else:
     
    760760                            val = getattr(rel_obj, f.rel.field_name)
    761761                        except AttributeError:
    762762                            raise TypeError, "Invalid value: %r should be a %s instance, not a %s" % (f.name, f.rel.to, type(rel_obj))
    763                 setattr(self, f.column, val)
     763                setattr(self, f.attname, val)
    764764            else:
    765                 val = kwargs.pop(f.name, f.get_default())
    766                 setattr(self, f.name, val)
     765                val = kwargs.pop(f.attname, f.get_default())
     766                setattr(self, f.attname, val)
    767767        if kwargs:
    768768            raise TypeError, "'%s' is an invalid keyword argument for this function" % kwargs.keys()[0]
    769769    for i, arg in enumerate(args):
    770         setattr(self, opts.fields[i].column, arg)
     770        setattr(self, opts.fields[i].attname, arg)
    771771
    772772def method_eq(opts, self, other):
    773     return isinstance(other, self.__class__) and getattr(self, opts.pk.column) == getattr(other, opts.pk.column)
     773    return isinstance(other, self.__class__) and getattr(self, opts.pk.attname) == getattr(other, opts.pk.attname)
    774774
    775775def method_save(opts, self):
    776776    # Run any pre-save hooks.
     
    780780    cursor = db.db.cursor()
    781781
    782782    # First, try an UPDATE. If that doesn't update anything, do an INSERT.
    783     pk_val = getattr(self, opts.pk.column)
     783    pk_val = getattr(self, opts.pk.attname)
    784784    pk_set = bool(pk_val)
    785785    record_exists = True
    786786    if pk_set:
     
    788788        cursor.execute("SELECT 1 FROM %s WHERE %s=%%s LIMIT 1" % (opts.db_table, opts.pk.column), [pk_val])
    789789        # If it does already exist, do an UPDATE.
    790790        if cursor.fetchone():
    791             db_values = [f.get_db_prep_save(f.pre_save(getattr(self, f.column), False)) for f in non_pks]
     791            db_values = [f.get_db_prep_save(f.pre_save(getattr(self, f.attname), False)) for f in non_pks]
    792792            cursor.execute("UPDATE %s SET %s WHERE %s=%%s" % (opts.db_table,
    793                 ','.join(['%s=%%s' % f.column for f in non_pks]), opts.pk.column),
     793                ','.join(['%s=%%s' % f.column for f in non_pks]), opts.pk.attname),
    794794                db_values + [pk_val])
    795795        else:
    796796            record_exists = False
    797797    if not pk_set or not record_exists:
    798798        field_names = [f.column for f in opts.fields if not isinstance(f, AutoField)]
    799799        placeholders = ['%s'] * len(field_names)
    800         db_values = [f.get_db_prep_save(f.pre_save(getattr(self, f.column), True)) for f in opts.fields if not isinstance(f, AutoField)]
     800        db_values = [f.get_db_prep_save(f.pre_save(getattr(self, f.attname), True)) for f in opts.fields if not isinstance(f, AutoField)]
    801801        if opts.order_with_respect_to:
    802802            field_names.append('_order')
    803803            # TODO: This assumes the database supports subqueries.
    804804            placeholders.append('(SELECT COUNT(*) FROM %s WHERE %s = %%s)' % \
    805805                (opts.db_table, opts.order_with_respect_to.column))
    806             db_values.append(getattr(self, opts.order_with_respect_to.column))
     806            db_values.append(getattr(self, opts.order_with_respect_to.attname))
    807807        cursor.execute("INSERT INTO %s (%s) VALUES (%s)" % (opts.db_table,
    808808            ','.join(field_names), ','.join(placeholders)), db_values)
    809809        if opts.has_auto_field:
    810             setattr(self, opts.pk.column, db.get_last_insert_id(cursor, opts.db_table, opts.pk.column))
     810            setattr(self, opts.pk.attname, db.get_last_insert_id(cursor, opts.db_table, opts.pk.column))
    811811    db.db.commit()
    812812    # Run any post-save hooks.
    813813    if hasattr(self, '_post_save'):
    814814        self._post_save()
    815815
    816816def method_delete(opts, self):
    817     assert getattr(self, opts.pk.column) is not None, "%r can't be deleted because it doesn't have an ID."
     817    assert getattr(self, opts.pk.attname) is not None, "%r can't be deleted because it doesn't have an ID."
    818818    # Run any pre-delete hooks.
    819819    if hasattr(self, '_pre_delete'):
    820820        self._pre_delete()
     
    833833                sub_obj.delete()
    834834    for rel_opts, rel_field in opts.get_all_related_many_to_many_objects():
    835835        cursor.execute("DELETE FROM %s WHERE %s_id=%%s" % (rel_field.get_m2m_db_table(rel_opts),
    836             self._meta.object_name.lower()), [getattr(self, opts.pk.column)])
     836            self._meta.object_name.lower()), [getattr(self, opts.pk.attname)])
    837837    for f in opts.many_to_many:
    838838        cursor.execute("DELETE FROM %s WHERE %s_id=%%s" % (f.get_m2m_db_table(opts), self._meta.object_name.lower()),
    839             [getattr(self, opts.pk.column)])
    840     cursor.execute("DELETE FROM %s WHERE %s=%%s" % (opts.db_table, opts.pk.column), [getattr(self, opts.pk.column)])
     839            [getattr(self, opts.pk.attname)])
     840    cursor.execute("DELETE FROM %s WHERE %s=%%s" % (opts.db_table, opts.pk.column), [getattr(self, opts.pk.attname)])
    841841    db.db.commit()
    842     setattr(self, opts.pk.column, None)
     842    setattr(self, opts.pk.attname, None)
    843843    for f in opts.fields:
    844         if isinstance(f, FileField) and getattr(self, f.column):
     844        if isinstance(f, FileField) and getattr(self, f.attname):
    845845            file_name = getattr(self, 'get_%s_filename' % f.name)()
    846846            # If the file exists and no other object of this type references it,
    847847            # delete it from the filesystem.
     
    856856        self._next_in_order_cache = opts.get_model_module().get_object(order_by=('_order',),
    857857            where=['_order > (SELECT _order FROM %s WHERE %s=%%s)' % (opts.db_table, opts.pk.column),
    858858                '%s=%%s' % order_field.column], limit=1,
    859             params=[getattr(self, opts.pk.column), getattr(self, order_field.column)])
     859            params=[getattr(self, opts.pk.attname), getattr(self, order_field.attname)])
    860860    return self._next_in_order_cache
    861861
    862862def method_get_previous_in_order(opts, order_field, self):
     
    864864        self._previous_in_order_cache = opts.get_model_module().get_object(order_by=('-_order',),
    865865            where=['_order < (SELECT _order FROM %s WHERE %s=%%s)' % (opts.db_table, opts.pk.column),
    866866                '%s=%%s' % order_field.column], limit=1,
    867             params=[getattr(self, opts.pk.column), getattr(self, order_field.column)])
     867            params=[getattr(self, opts.pk.attname), getattr(self, order_field.attname)])
    868868    return self._previous_in_order_cache
    869869
    870870# RELATIONSHIP METHODS #####################
     
    873873def method_get_many_to_one(field_with_rel, self):
    874874    cache_var = field_with_rel.get_cache_name()
    875875    if not hasattr(self, cache_var):
    876         val = getattr(self, field_with_rel.column)
     876        val = getattr(self, field_with_rel.attname)
    877877        mod = field_with_rel.rel.to.get_model_module()
    878878        if val is None:
    879879            raise getattr(mod, '%sDoesNotExist' % field_with_rel.rel.to.object_name)
     
    893893            field_with_rel.get_m2m_db_table(self._meta), rel.pk.column,
    894894            rel.object_name.lower(), self._meta.object_name.lower(), rel.get_order_sql('a'))
    895895        cursor = db.db.cursor()
    896         cursor.execute(sql, [getattr(self, self._meta.pk.column)])
     896        cursor.execute(sql, [getattr(self, self._meta.pk.attname)])
    897897        setattr(self, cache_var, [getattr(mod, rel.object_name)(*row) for row in cursor.fetchall()])
    898898    return getattr(self, cache_var)
    899899
     
    914914    rel = rel_field.rel.to
    915915    m2m_table = rel_field.get_m2m_db_table(self._meta)
    916916    cursor = db.db.cursor()
    917     this_id = getattr(self, self._meta.pk.column)
     917    this_id = getattr(self, self._meta.pk.attname)
    918918    if ids_to_delete:
    919919        sql = "DELETE FROM %s WHERE %s_id = %%s AND %s_id IN (%s)" % (m2m_table, self._meta.object_name.lower(), rel.object_name.lower(), ','.join(map(str, ids_to_delete)))
    920920        cursor.execute(sql, [this_id])
     
    941941# Handles adding related objects.
    942942# Example: Poll.add_choice()
    943943def method_add_related(rel_obj, rel_mod, rel_field, self, *args, **kwargs):
    944     init_kwargs = dict(zip([f.name for f in rel_obj.fields if f != rel_field and not isinstance(f, AutoField)], args))
     944    init_kwargs = dict(zip([f.attname for f in rel_obj.fields if f != rel_field and not isinstance(f, AutoField)], args))
    945945    init_kwargs.update(kwargs)
    946946    for f in rel_obj.fields:
    947947        if isinstance(f, AutoField):
    948             init_kwargs[f.name] = None
     948            init_kwargs[f.attname] = None
    949949    init_kwargs[rel_field.name] = self
    950950    obj = rel_mod.Klass(**init_kwargs)
    951951    obj.save()
     
    954954# Handles related many-to-many object retrieval.
    955955# Examples: Album.get_song(), Album.get_song_list(), Album.get_song_count()
    956956def method_get_related_many_to_many(method_name, opts, rel_mod, rel_field, self, **kwargs):
    957     kwargs['%s__%s__exact' % (rel_field.name, opts.pk.name)] = getattr(self, opts.pk.column)
     957    kwargs['%s__%s__exact' % (rel_field.name, opts.pk.name)] = getattr(self, opts.pk.attname)
    958958    return getattr(rel_mod, method_name)(**kwargs)
    959959
    960960# Handles setting many-to-many related objects.
     
    963963    id_list = map(int, id_list) # normalize to integers
    964964    rel = rel_field.rel.to
    965965    m2m_table = rel_field.get_m2m_db_table(rel_opts)
    966     this_id = getattr(self, self._meta.pk.column)
     966    this_id = getattr(self, self._meta.pk.attname)
    967967    cursor = db.db.cursor()
    968968    cursor.execute("DELETE FROM %s WHERE %s_id = %%s" % (m2m_table, rel.object_name.lower()), [this_id])
    969969    sql = "INSERT INTO %s (%s_id, %s_id) VALUES (%%s, %%s)" % (m2m_table, rel.object_name.lower(), rel_opts.object_name.lower())
     
    992992
    993993def method_get_next_or_previous(get_object_func, field, is_next, self, **kwargs):
    994994    kwargs.setdefault('where', []).append('%s %s %%s' % (field.column, (is_next and '>' or '<')))
    995     kwargs.setdefault('params', []).append(str(getattr(self, field.name)))
     995    kwargs.setdefault('params', []).append(str(getattr(self, field.attname)))
    996996    kwargs['order_by'] = [(not is_next and '-' or '') + field.name]
    997997    kwargs['limit'] = 1
    998998    return get_object_func(**kwargs)
     
    10001000# CHOICE-RELATED METHODS ###################
    10011001
    10021002def method_get_display_value(field, self):
    1003     value = getattr(self, field.column)
     1003    value = getattr(self, field.attname)
    10041004    return dict(field.choices).get(value, value)
    10051005
    10061006# FILE-RELATED METHODS #####################
    10071007
    10081008def method_get_file_filename(field, self):
    1009     return os.path.join(settings.MEDIA_ROOT, getattr(self, field.name))
     1009    return os.path.join(settings.MEDIA_ROOT, getattr(self, field.attname))
    10101010
    10111011def method_get_file_url(field, self):
    1012     if getattr(self, field.name): # value is not blank
     1012    if getattr(self, field.attname): # value is not blank
    10131013        import urlparse
    1014         return urlparse.urljoin(settings.MEDIA_URL, getattr(self, field.name)).replace('\\', '/')
     1014        return urlparse.urljoin(settings.MEDIA_URL, getattr(self, field.attname)).replace('\\', '/')
    10151015    return ''
    10161016
    10171017def method_get_file_size(field, self):
     
    10361036            filename = filename[:dot_index] + '_' + filename[dot_index:]
    10371037
    10381038    # Write the file to disk.
    1039     setattr(self, field.name, filename)
     1039    setattr(self, field.attname, filename)
    10401040    fp = open(getattr(self, 'get_%s_filename' % field.name)(), 'wb')
    10411041    fp.write(raw_contents)
    10421042    fp.close()
     
    13631363    kwargs['where'] = ["%s.%s IN (%s)" % (opts.db_table, opts.pk.column, ",".join(['%s'] * len(id_list)))]
    13641364    kwargs['params'] = id_list
    13651365    obj_list = function_get_list(opts, klass, **kwargs)
    1366     return dict([(getattr(o, opts.pk.column), o) for o in obj_list])
     1366    return dict([(getattr(o, opts.pk.attname), o) for o in obj_list])
    13671367
    13681368def function_get_latest(opts, klass, does_not_exist_exception, **kwargs):
    13691369    kwargs['order_by'] = ('-' + opts.get_latest_by,)
     
    14331433                lookup_kwargs = opts.one_to_one_field.rel.limit_choices_to
    14341434                lookup_kwargs['%s__exact' % opts.one_to_one_field.rel.field_name] = obj_key
    14351435                _ = opts.one_to_one_field.rel.to.get_model_module().get_object(**lookup_kwargs)
    1436                 params = dict([(f.column, f.get_default()) for f in opts.fields])
    1437                 params[opts.pk.column] = obj_key
     1436                params = dict([(f.attname, f.get_default()) for f in opts.fields])
     1437                params[opts.pk.attname] = obj_key
    14381438                self.original_object = opts.get_model_module().Klass(**params)
    14391439            else:
    14401440                raise
     
    14701470        # Fields with auto_now_add are another special case; they should keep
    14711471        # their original value in the change stage.
    14721472        if change and getattr(f, 'auto_now_add', False):
    1473             params[f.column] = getattr(self.original_object, f.name)
     1473            params[f.attname] = getattr(self.original_object, f.attname)
    14741474        else:
    1475             params[f.column] = f.get_manipulator_new_data(new_data)
     1475            params[f.attname] = f.get_manipulator_new_data(new_data)
    14761476
    14771477    if change:
    1478         params[opts.pk.column] = self.obj_key
     1478        params[opts.pk.attname] = self.obj_key
    14791479
    14801480    # First, save the basic object itself.
    14811481    new_object = klass(**params)
     
    14901490    if change:
    14911491        self.fields_added, self.fields_changed, self.fields_deleted = [], [], []
    14921492        for f in opts.fields:
    1493             if not f.primary_key and str(getattr(self.original_object, f.column)) != str(getattr(new_object, f.column)):
     1493            if not f.primary_key and str(getattr(self.original_object, f.attname)) != str(getattr(new_object, f.attname)):
    14941494                self.fields_changed.append(f.verbose_name)
    14951495
    14961496    # Save many-to-many objects. Example: Poll.set_sites()
     
    15261526                old_rel_obj = None
    15271527                if rel_new_data[rel_opts.pk.name][0]:
    15281528                    try:
    1529                         old_rel_obj = getattr(self.original_object, 'get_%s' % opts.get_rel_object_method_name(rel_opts, rel_field))(**{'%s__exact' % rel_opts.pk.name: rel_new_data[rel_opts.pk.name][0]})
     1529                        old_rel_obj = getattr(self.original_object, 'get_%s' % opts.get_rel_object_method_name(rel_opts, rel_field))(**{'%s__exact' % rel_opts.pk.name: rel_new_data[rel_opts.pk.attname][0]})
    15301530                    except ObjectDoesNotExist:
    15311531                        pass
    15321532
     
    15401540                # given, use a default value. FileFields are also a special
    15411541                # case, because they'll be dealt with later.
    15421542                if change and (isinstance(f, FileField) or not f.editable):
    1543                     if rel_new_data.get(rel_opts.pk.name, False) and rel_new_data[rel_opts.pk.name][0]:
    1544                         params[f.column] = getattr(old_rel_obj, f.column)
     1543                    if rel_new_data.get(rel_opts.pk.attname, False) and rel_new_data[rel_opts.pk.attname][0]:
     1544                        params[f.attname] = getattr(old_rel_obj, f.attname)
    15451545                    else:
    1546                         params[f.column] = f.get_default()
     1546                        params[f.attname] = f.get_default()
    15471547                elif f == rel_field:
    1548                     params[f.column] = getattr(new_object, rel_field.rel.field_name)
     1548                    params[f.attname] = getattr(new_object, rel_field.rel.field_name)
    15491549                elif add and isinstance(f, AutoField):
    1550                     params[f.column] = None
     1550                    params[f.attname] = None
    15511551                else:
    1552                     params[f.column] = f.get_manipulator_new_data(rel_new_data, rel=True)
     1552                    params[f.attname] = f.get_manipulator_new_data(rel_new_data, rel=True)
    15531553                # Related links are a special case, because we have to
    15541554                # manually set the "content_type_id" and "object_id" fields.
    15551555                if opts.has_related_links and rel_opts.module_name == 'relatedlinks':
     
    15661566
    15671567                # Save any uploaded files.
    15681568                for f in rel_opts.fields:
    1569                     if isinstance(f, FileField) and rel_new_data.get(f.name, False):
     1569                    if isinstance(f, FileField) and rel_new_data.get(f.attname, False):
    15701570                        f.save_file(rel_new_data, new_rel_obj, change and old_rel_obj or None, old_rel_obj is not None, rel=True)
    15711571
    15721572                # Calculate whether any fields have changed.
     
    15751575                        self.fields_added.append('%s "%r"' % (rel_opts.verbose_name, new_rel_obj))
    15761576                    else:
    15771577                        for f in rel_opts.fields:
    1578                             if not f.primary_key and f != rel_field and str(getattr(old_rel_obj, f.column)) != str(getattr(new_rel_obj, f.column)):
     1578                            if not f.primary_key and f != rel_field and str(getattr(old_rel_obj, f.attname)) != str(getattr(new_rel_obj, f.attname)):
    15791579                                self.fields_changed.append('%s for %s "%r"' % (f.verbose_name, rel_opts.verbose_name, new_rel_obj))
    15801580
    15811581                # Save many-to-many objects.
    15821582                for f in rel_opts.many_to_many:
    15831583                    if not f.rel.edit_inline:
    1584                         was_changed = getattr(new_rel_obj, 'set_%s' % f.name)(rel_new_data[f.name])
     1584                        was_changed = getattr(new_rel_obj, 'set_%s' % f.name)(rel_new_data[f.attname])
    15851585                        if change and was_changed:
    15861586                            self.fields_changed.append('%s for %s "%s"' % (f.verbose_name, rel_opts.verbose_name, new_rel_obj))
    15871587
    15881588            # If, in the change stage, all of the core fields were blank and
    15891589            # the primary key (ID) was provided, delete the item.
    1590             if change and all_cores_blank and rel_new_data.has_key(rel_opts.pk.name) and rel_new_data[rel_opts.pk.name][0]:
     1590            if change and all_cores_blank and rel_new_data.has_key(rel_opts.pk.attname) and rel_new_data[rel_opts.pk.attname][0]:
    15911591                new_rel_obj.delete()
    15921592                self.fields_deleted.append('%s "%r"' % (rel_opts.verbose_name, old_rel_obj))
    15931593
     
    16061606    else:
    16071607        kwargs = {'%s__iexact' % field_name_list[0]: field_data}
    16081608    for f in field_list[1:]:
    1609         field_val = all_data.get(f.column, None)
     1609        field_val = all_data.get(f.attname, None)
    16101610        if field_val is None:
    16111611            # This will be caught by another validator, assuming the field
    16121612            # doesn't have blank=True.
     
    16201620        old_obj = mod.get_object(**kwargs)
    16211621    except ObjectDoesNotExist:
    16221622        return
    1623     if hasattr(self, 'original_object') and getattr(self.original_object, opts.pk.column) == getattr(old_obj, opts.pk.column):
     1623    if hasattr(self, 'original_object') and getattr(self.original_object, opts.pk.attname) == getattr(old_obj, opts.pk.attname):
    16241624        pass
    16251625    else:
    16261626        raise validators.ValidationError, "%s with this %s already exists for the given %s." % \
     
    16461646    except ObjectDoesNotExist:
    16471647        return
    16481648    else:
    1649         if hasattr(self, 'original_object') and getattr(self.original_object, opts.pk.column) == getattr(old_obj, opts.pk.column):
     1649        if hasattr(self, 'original_object') and getattr(self.original_object, opts.pk.attname) == getattr(old_obj, opts.pk.attname):
    16501650            pass
    16511651        else:
    16521652            format_string = (lookup_type == 'date') and '%B %d, %Y' or '%B %Y'
  • django/core/meta/fields.py

     
    5555        old_obj = opts.get_model_module().get_object(**{'%s__%s' % (f.name, lookup_type): field_data})
    5656    except ObjectDoesNotExist:
    5757        return
    58     if hasattr(self, 'original_object') and getattr(self.original_object, opts.pk.column) == getattr(old_obj, opts.pk.column):
     58    if hasattr(self, 'original_object') and getattr(self.original_object, opts.pk.attname) == getattr(old_obj, opts.pk.attname):
    5959        return
    6060    raise validators.ValidationError, "%s with this %s already exists." % (capfirst(opts.verbose_name), f.verbose_name)
    6161
     62
     63# A guide to Field parameters:
     64#
     65#   * name:      The name of the field specifed in the model.
     66#   * attname:   The attribute to use on the model object. This is the same as
     67#                "name", except in the case of ForeignKeys, where "_id" is
     68#                appended.
     69#   * db_column: The db_column specified in the model (or None).
     70#   * column:    The database column for this field. This is the same as
     71#                "attname", except if db_column is specified.
     72#
     73# Code that introspects values, or does other dynamic things, should use
     74# attname. For example, this gets the primary key value of object "obj":
     75#
     76#     getattr(obj, opts.pk.attname)
     77
    6278class Field(object):
    6379
    6480    # Designates whether empty strings fundamentally are allowed at the
     
    110126        self.creation_counter = Field.creation_counter
    111127        Field.creation_counter += 1
    112128
    113         # Set the name of the database column.
    114         self.column = self.get_db_column()
     129        self.attname, self.column = self.get_attname_column()
    115130
    116131    def set_name(self, name):
    117132        self.name = name
    118133        self.verbose_name = self.verbose_name or name.replace('_', ' ')
    119         self.column = self.get_db_column()
     134        self.attname, self.column = self.get_attname_column()
    120135
    121     def get_db_column(self):
    122         if self.db_column: return self.db_column
     136    def get_attname_column(self):
    123137        if isinstance(self.rel, ManyToOne):
    124             return '%s_id' % self.name
    125         return self.name
     138            attname = '%s_id' % self.name
     139        else:
     140            attname = self.name
     141        column = self.db_column or attname
     142        return attname, column
    126143
    127144    def get_cache_name(self):
    128145        return '_%s_cache' % self.name
     
    277294        if self.choices:
    278295            return first_choice + list(self.choices)
    279296        rel_obj = self.rel.to
    280         return first_choice + [(getattr(x, rel_obj.pk.column), repr(x)) for x in rel_obj.get_model_module().get_list(**self.rel.limit_choices_to)]
     297        return first_choice + [(getattr(x, rel_obj.pk.attname), repr(x)) for x in rel_obj.get_model_module().get_list(**self.rel.limit_choices_to)]
    281298
    282299class AutoField(Field):
    283300    empty_strings_allowed = False
Back to Top