Opened 4 years ago

Closed 4 years ago

#31899 closed Bug (duplicate)

unexpected behaviour of get_or_create when one of the kwargs is None

Reported by: MathiasWedeken Owned by: nobody
Component: Database layer (models, ORM) Version: 3.0
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Assuming a db-model like this:

class SomeModel(models.Model): 
    field_1 = models.CharField(max_length=100)
    field_2 = models.JSONField()

In versions prior to 3.0, get_or_create would expect like this:

#first time
SomeModel.objects.get_or_create(field_1="bla", field_2=None)
--> (<SomeModel: bla>, True)

#second_time
SomeModel.objects.get_or_create(field_1="bla", field_2=None)
--> (<SomeModel: bla>, False)

And of course, querying for all objects would give this:

SomeModel.objects.filter(field_1="bla")
--> <QuerySet [<SomeModel: bla>]> 

In version 3.0.9, however, this happens:

#second_time in django 3.0.9
SomeModel.objects.get_or_create(field_1="bla", field_2=None)
--> (<SomeModel: bla>, True)

and querying for all objects returns:

SomeModel.objects.filter(field_1="bla")
--> <QuerySet [<SomeModel: bla>,<SomeModel: bla>]> 

Change History (1)

comment:1 by Mariusz Felisiak, 4 years ago

Resolution: duplicate
Status: newclosed

Thanks for this ticket, however it works exactly the same for me in Django 2.2, 3.0, and with the new implementation in Django 3.1:

>>> JSONModel.objects.get_or_create(field_1="bla", field_2=None)
(<JSONModel: JSONModel object (1)>, True)
>>> JSONModel.objects.get_or_create(field_1="bla", field_2=None)
(<JSONModel: JSONModel object (2)>, True)

field_2 doesn't accept NULL (SQL) so I believe you want to use null (JSON) value, in such cases you should use Value('null') which works as expected:

>>> JSONModel.objects.get_or_create(field_1="bla", field_2=Value('null'))
(<JSONModel: JSONModel object (1)>, True)
>>> JSONModel.objects.get_or_create(field_1="bla", field_2=Value('null'))
(<JSONModel: JSONModel object (1)>, False)

see also docs about storing and querying for None.

I don't think there is much we can do without making the relation between NULL (SQL) and null (JSON) even more confusing. Closing as a duplicate of #31324.

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