Look up an object with the given kwargs, updating one with defaults if it exists, otherwise create a new one. Optionally, an object can be created with different values than defaults by using create_defaults. Return a tuple (object, created), where created is
(self, defaults=None, create_defaults=None, **kwargs)
| 1054 | aget_or_create.alters_data = True |
| 1055 | |
| 1056 | def update_or_create(self, defaults=None, create_defaults=None, **kwargs): |
| 1057 | """ |
| 1058 | Look up an object with the given kwargs, updating one with defaults |
| 1059 | if it exists, otherwise create a new one. Optionally, an object can |
| 1060 | be created with different values than defaults by using |
| 1061 | create_defaults. |
| 1062 | Return a tuple (object, created), where created is a boolean |
| 1063 | specifying whether an object was created. |
| 1064 | """ |
| 1065 | update_defaults = defaults or {} |
| 1066 | if create_defaults is None: |
| 1067 | create_defaults = update_defaults |
| 1068 | |
| 1069 | self._for_write = True |
| 1070 | with transaction.atomic(using=self.db): |
| 1071 | # Lock the row so that a concurrent update is blocked until |
| 1072 | # update_or_create() has performed its save. |
| 1073 | obj, created = self.select_for_update().get_or_create( |
| 1074 | create_defaults, **kwargs |
| 1075 | ) |
| 1076 | if created: |
| 1077 | return obj, created |
| 1078 | for k, v in resolve_callables(update_defaults): |
| 1079 | setattr(obj, k, v) |
| 1080 | |
| 1081 | update_fields = set(update_defaults) |
| 1082 | concrete_field_names = self.model._meta._non_pk_concrete_field_names |
| 1083 | # update_fields does not support non-concrete fields. |
| 1084 | if concrete_field_names.issuperset(update_fields): |
| 1085 | # Add fields which are set on pre_save(), e.g. auto_now fields. |
| 1086 | # This is to maintain backward compatibility as these fields |
| 1087 | # are not updated unless explicitly specified in the |
| 1088 | # update_fields list. |
| 1089 | pk_fields = self.model._meta.pk_fields |
| 1090 | for field in self.model._meta.local_concrete_fields: |
| 1091 | if not ( |
| 1092 | field in pk_fields or field.__class__.pre_save is Field.pre_save |
| 1093 | ): |
| 1094 | update_fields.add(field.name) |
| 1095 | if field.name != field.attname: |
| 1096 | update_fields.add(field.attname) |
| 1097 | obj.save(using=self.db, update_fields=update_fields) |
| 1098 | else: |
| 1099 | obj.save(using=self.db) |
| 1100 | return obj, False |
| 1101 | |
| 1102 | update_or_create.alters_data = True |
| 1103 |