Opened 4 years ago

Closed 4 years ago

#16767 closed Bug (invalid)

get_or_create does not raise error even though i didn't give a primary key to it

Reported by: haandol Owned by: nobody
Component: Database layer (models, ORM) Version: 1.3
Severity: Normal Keywords: model, get_or_create
Cc: anssi.kaariainen@…, adammckerlie@… Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

here is the example model

class User(models.Model):                                                                                             
    id = models.CharField(max_length=128, primary_key=True)
    email = models.EmailField(unique=True)                                                      
    created = models.DateField(auto_now_add=True)

and here is view code

user, isnew = User.objects.get_or_create(email='setsquaretech@gmail.com')

I expected the prev view code raises a kind of database error, but it added a record on the database with 'empty primary key' normally.

Change History (5)

comment:1 Changed 4 years ago by ptone

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

If this is a bug this is a bug at a lower level of the model.save - as that only generates an error if you specify a conflicting PK, when using a manual PK.

If this is not a bug, then it should be considered a candidate for clarification in the documentation, as it is completely ambiguous about the behavior you should expect.

One could argue that if a PK is required in the model (which is specified in the docs) then it could be argued that a PK value should be required.

comment:2 Changed 4 years ago by akaariai

  • Cc anssi.kaariainen@… added
  • Triage Stage changed from Unreviewed to Accepted

I can see the bug here - the get_or_create will create a user with id = . That seems confusing. The reason is probably the treatment of None as empty string (not that I have actually verified this is the case).

The same problem is with .save(), User(email='foobar@…').save() will save a user with id = .

In effect CharField has a default value of , and I guess that for primary keys that is not the wanted behavior.

Version 0, edited 4 years ago by akaariai (next)

comment:3 Changed 4 years ago by silent1mezzo

What would you have it be set as though? A character primary key can be anything. Wouldn't having it as:

id = models.AutoField(primary_key=True)

be a better?

comment:4 Changed 4 years ago by silent1mezzo

  • Cc adammckerlie@… added

comment:5 Changed 4 years ago by ptone

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

This is actually consistent with the docs. You can only create one instance in the DB of the object with a PK of without error, if you try to create another user object with this same primary key - you will get the integrity error as documented. In other words may be silly as a PK, but is valid.

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