Opened 18 years ago

Closed 17 years ago

#1394 closed defect (fixed)

primary_key with db_column set results in errors in admin

Reported by: mooquack@… Owned by: nobody
Component: contrib.admin Version: dev
Severity: normal Keywords: primary key admin onetoonefield db_column
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Take the following model, for example:

class A(meta.Model):
    pri_key = meta.AutoField('ID', db_column='id', primary_key=True)
    title = meta.CharField(maxlength=30)

    class META:
        admin = meta.Admin(
            fields = (
                (None, {'fields': ('title',)}),
            ),
            list_display = ('title',),
        )

    def __repr__(self):
        return self.title

If an object of this model is edited in the admin, clicking "save" will result in a ProgrammingError like the following:

ProgrammingError at /admin/testapp/as/1/
ERROR: column "pri_key" does not exist UPDATE "testapp_as" SET "title"='Blah blah blah' WHERE "pri_key"='1'

In short, the admin is not listening to pri_key's db_column option. Searching through the code finds a few places where it was assumed the primary key's name and db column would never be different. Since I'm not sure how to create a diff (embarrased cough), here are the lines of code that need to be changed:

In django/core/meta/__init__.py, line 1006:
                db.db.quote_name(opts.pk.attname)),
Becomes:
                db.db.quote_name(opts.pk.column)),
In django/contrib/admin/views/main.py, line 453:
    pk_value = getattr(new_object, opts.pk.column)
Becomes:
    pk_value = getattr(new_object, opts.pk.attname)

It works flawlessly after making these changes.

Change History (7)

comment:1 by Antti Kaihola, 18 years ago

Summary: Primary key with db_column set results in errors in adminPrimary key with db_column set results in errors in admin [also in magic-removal]

I hit a similar bug in magic-removal. If the field name and the db_column value are different, admin gives an error when I try to select an object to change. The error is:

Traceback (most recent call last):
File "django/template/__init__.py" in render_node
  683. result = node.render(context)
File "django/template/__init__.py" in render
  729. output = self.filter_expression.resolve(context)
File "django/template/__init__.py" in resolve
  537. obj = resolve_variable(self.var, context)
File "django/template/__init__.py" in resolve_variable
  625. current = current()
File "django/contrib/admin/views/main.py" in original_value
  137. return self.original.__dict__[self.field.column]

  KeyError at /admin/myapp/person/1/
  'Person_ID'

My model is:

class Person(models.Model):
    id = models.IntegerField(primary_key = True, db_column   = 'Person_ID')
    name = models.CharField(maxlength = 100)

comment:2 by anonymous, 18 years ago

milestone: Version 0.91Version 0.92

comment:3 by Gary Wilson <gary.wilson@…>, 18 years ago

milestone: Version 0.92Version 1.0

0.92 is long gone.

comment:4 by (none), 17 years ago

milestone: Version 1.0

Milestone Version 1.0 deleted

comment:5 by Gary Wilson <gary.wilson@…>, 17 years ago

Summary: Primary key with db_column set results in errors in admin [also in magic-removal]primary_key with db_column set results in errors in admin
Triage Stage: UnreviewedAccepted
Version: 0.91SVN

Marking this as accepted, since it seems like an obvious bug that should be fixed. It also appears to still be unfixed, since reporter of #3332 has the same issue.

comment:6 by anonymous, 17 years ago

line: 136 on django/contrib/admin/views/main.py

    def original_value(self):
        if self.original:
#            return self.original.__dict__[self.field.column]
            return self.original.__dict__[self.field.attname]

comment:7 by Malcolm Tredinnick, 17 years ago

Resolution: fixed
Status: newclosed

(In [6360]) Fixed #1394 -- Fixed an admin crash when saving models with pk db column != pk attname.

Note: See TracTickets for help on using tickets.
Back to Top