Code

Opened 7 years ago

Closed 7 years ago

#5139 closed (wontfix)

Custom primary_key broken when saving

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

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

Attachments (0)

Change History (3)

comment:1 Changed 7 years ago by Fredrik Lundh <fredrik@…>

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

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 Changed 7 years ago by Fredrik Lundh <fredrik@…>

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 Changed 7 years ago by mtredinnick

  • Resolution set to wontfix
  • Status changed from new to closed

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.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.