4

I understand that get_or_create is now deprecated in favour of using upsert, but how do I make update_one to return the object rather the number of objects modified, and can I just retrieve an object if I don't want to update anything?

e.g.

Model.objects.get_or_create(first_name='John', last_name='Potter', age=40)
# assuming that first_name + last_name + age are enough to uniquiely indentify a person   

returns a Model object (a new object if it didn't exist, and existing object if it does). What would be the equivalent of this using the new method?

Model.objects(first_name='John', last_name='Potter', age=40).update_one(upsert=True)
# returns number of objects (1)
Model.objects(first_name='John', last_name='Potter', age=40).update_one(set__first_name='John', set__last_name='Potter', set__age=40,upsert=True)
# returns number of objects (1)

Is there a way to make it return the object, and make it behave exactly like get_or_create?

I couldn't find how to do this in the documentation

confused00
  • 2,556
  • 21
  • 39

2 Answers2

12

You are very close but you need to use a findAndModify command via modify rather than an update command.

NewDoc = Model.objects(first_name='John', 
                       last_name='Potter', 
                       age=40).modify(upsert=True, new=True,
                                      set__first_name='John, 
                                      set__last_name='Potter', 
                                      set__age=40,
                                      set_on_insert__newUser=True)

Take note of the first 2 modify kwargs - upsert and new. Also take note of the $setOnInsert operator example which will only set a field if the findAndModify does an upsert.

Voicu
  • 16,921
  • 10
  • 60
  • 69
Ross
  • 17,861
  • 2
  • 55
  • 73
  • Thanks for the answer. But do you have any idea why do I get a `'QuerySet' object has no attribute 'modify'`? – confused00 Sep 16 '14 at 08:24
  • Oh it seems the `modify` command has been made available since 0.9, but the lastest pip version appears to be 0.8.7 – confused00 Sep 16 '14 at 08:35
  • You'll have to install from master via pip. See: http://stackoverflow.com/questions/20101834/pip-install-from-github-repo-branch – Ross Sep 16 '14 at 10:20
  • @Ross so to determine if it's a new doc, I have to create `newUser` field only for this purpose? Looks like an ugly hack, or there is a better way? – warvariuc Nov 30 '15 at 13:25
1

You should look at modify. Passing a new=True you'll get the updated object (or document, in mongodb parlance).

Voicu
  • 16,921
  • 10
  • 60
  • 69
Germano
  • 2,452
  • 18
  • 25