Opened 17 years ago

Closed 17 years ago

#5139 closed (wontfix)

Custom primary_key broken when saving

Reported by: bjorn.kempen@… Owned by: nobody
Component: Database layer (models, ORM) Version: dev
Severity: Keywords: primary_key save
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

When you save a model instance with a custom primary_key, you can't retrieve the primary_key without getting the instance again first.
With a standard primary_key this works fine (like the documentation says)

Relevant code from my models

class XbtFiles(models.Model):
  fid = models.IntegerField(primary_key=True)
  info_hash = models.TextField(unique=True)

class Tag(models.Model):
    name = models.CharField(maxlength=128)

With standard primary_key it works fine

>>> t=Tag(name="foo")
>>> t.save()
>>> t.id
2L

With custom primary_key it is broken

>>> x=XbtFiles(info_hash="this_field_is_unique")
>>> x.save()
>>> x.info_hash
'this_field_is_unique'
>>> x.fid
>>> #huh nothing???
>>> y=XbtFiles.objects.get(info_hash="this_field_is_unique")
>>> x == y
False
>>> y.fid
10L

Change History (3)

comment:1 by Fredrik Lundh <fredrik@…>, 17 years ago

Removing the has_auto_field check seems to fix this, but it's probably there for a reason:

Index: ../django/db/models/base.py
==================================================================
-- ../django/db/models/base.py (revision 6184)
++ ../django/db/models/base.py (working copy)
@ -254,7 +254,7 @@
                cursor.execute("INSERT INTO %s (%s) VALUES (%s)" %
                    (qn(self._meta.db_table), qn(self._meta.pk.column),
                     connection.ops.pk_default_value()))
            if self._meta.has_auto_field and not pk_set:
            if not pk_set:
                setattr(self, self._meta.pk.attname, connection.ops.last_insert
id(cursor, self._meta.db_table, self._meta.pk.column))
        transaction.commit_unless_managed()

comment:2 by Fredrik Lundh <fredrik@…>, 17 years ago

Argh. Trying again:

Index: ../django/db/models/base.py
===================================================================
--- ../django/db/models/base.py (revision 6184)
+++ ../django/db/models/base.py (working copy)
@@ -254,7 +254,7 @@
                 cursor.execute("INSERT INTO %s (%s) VALUES (%s)" %
                     (qn(self._meta.db_table), qn(self._meta.pk.column),
                      connection.ops.pk_default_value()))
-            if self._meta.has_auto_field and not pk_set:
+            if not pk_set:
                 setattr(self, self._meta.pk.attname, connection.ops.last_insert
_id(cursor, self._meta.db_table, self._meta.pk.column))
         transaction.commit_unless_managed()

comment:3 by Malcolm Tredinnick, 17 years ago

Resolution: wontfix
Status: newclosed

Why do you expect this to do anything? If you have a manual pk field, you have to set it yourself. So it already exists on the model. If you want an autoincrementing field, use an AutoField, not an Integer Field (and we'll fill it in for you).

Please reopen if I've overlooked something here, but the behaviour you are expecting doesn't seem logical.

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