I think the scenario you're suggesting is just a little too complex for
update_or_create. It doesn't actually fetch the updated model instance .
You can instead write out what you want without too much extra code using
get_or_create, ensuring there's a transaction and select_for_update() to
lock the object whilst you modify it:

with transaction.atomic():
    obj, created =
Model.objects.select_for_update().get_or_create(key=some_key,
defaults={"json_field": fresh_json})
    if not created:
        obj.json_field = merge_json(obj.json_field, fresh_json)
        obj.save()

If you look inside update_or_create you'll see it essentially does this
already. If you use the pattern frequently, you can always wrap it up in
your own method.

On Mon, 26 Oct 2020 at 18:23, James Pulec <jpu...@gmail.com> wrote:

> Since update_or_create supports callables in the defaults dictionary, I'm
> wondering if it's worth considering passing the existing instance (if one
> is found) to those callables when resolving them.
>
> The scenario I'm running into involves wanting to merge json data.
> Basically, I have a JSON field on the model that I'd like to do an
> update_or_create for, but in the case where there's an existing instance
> and I'd be performing an update, I'd like the merge the existing JSON data
> with the data I'm passing to my defaults.
>
> One way I can imagine solving for this case is to pass the existing model
> instance to callables defined in the defaults dictionary, if an existing
> model instance is found.
>
> This does feel a little gross, since you'll need to check if the passed
> value is None, so definitely open to other suggestion.s.
>
> Wanted to post this here before on Trac to see if there's interest, better
> solutions, or any concerns.
>
> Thanks!
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django developers (Contributions to Django itself)" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-developers+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/f44a3f50-1d01-467f-988e-8d43537a8f98n%40googlegroups.com
> <https://groups.google.com/d/msgid/django-developers/f44a3f50-1d01-467f-988e-8d43537a8f98n%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>


-- 
Adam

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CAMyDDM2F8S_3kAdvb9JRH2V9y4BE%2BJSCXkXDGDrX8HPpe2B69Q%40mail.gmail.com.

Reply via email to