Подтвердить что ты не робот

Создайте модель Django или обновите ее, если она существует

Я хочу создать объект модели, например Person, если идентификатор пользователя не существует, или я получу объект этого человека.

Код для создания нового человека следующим образом:

class Person(models.Model):
    identifier = models.CharField(max_length = 10)
    name = models.CharField(max_length = 20)
    objects = PersonManager()

class PersonManager(models.Manager):
    def create_person(self, identifier):
        person = self.create(identifier = identifier)
        return person

Но я не знаю, где проверить и получить существующий объект.

4b9b3361

Ответ 1

Если вы ищете вариант "update if exists else create", пожалуйста, обратитесь к @Zags отличному ответу


Django уже имеет get_or_create, https://docs.djangoproject.com/en/dev/ref/models/querysets/#get-or-create

Для вас это может быть:

id = 'some identifier'
person, created = Person.objects.get_or_create(identifier=id)

if created:
   # means you have created a new person
else:
   # person just refers to the existing one

Ответ 2

Неясно, запрашивает ли ваш вопрос метод get_or_create (доступный, по крайней мере, от Django 1.3) или update_or_create (новый в Django 1.7). Это зависит от того, как вы хотите обновить объект пользователя.

Пример использования:

# In both cases, the call will get a person object with matching
# identifier or create one if none exists; if a person is created,
# it will be created with name equal to the value in `name`.

# In this case, if the Person already exists, its existing name is preserved
person, created = Person.objects.get_or_create(
        identifier=identifier, defaults={"name": name}
)

# In this case, if the Person already exists, its name is updated
person, created = Person.objects.update_or_create(
        identifier=identifier, defaults={"name": name}
)

Ответ 3

В Django есть поддержка, проверьте get_or_create

person, created = Person.objects.get_or_create(name='abc')
if created:
    # A new person object created
else:
    # person object already exists

Ответ 4

Думаю, я бы добавил ответ, так как название вопроса выглядит так, как будто оно спрашивает, как создавать или обновлять, а не создавать или создавать, как описано в теле вопроса.

Если вы хотите создать или обновить объект, метод .save() уже имеет это поведение по умолчанию, документы:

Django абстрагирует необходимость использования операторов INSERT или UPDATE SQL. В частности, когда вы вызываете save(), Django следует этому алгоритму:

Если для атрибута первичного ключа объектов установлено значение, которое оценивает на True (то есть значение, отличное от None или пустая строка), Django выполняет UPDATE. Если атрибут первичного ключа объектов не задан или если UPDATE ничего не обновлял, Django выполняет INSERT.

Стоит отметить, что, когда они говорят "если UPDATE ничего не обновлял", они в основном ссылаются на случай, когда идентификатор, предоставленный объекту, еще не существует в базе данных.

Ответ 5

Если один из входных данных при создании является первичным ключом, этого будет достаточно:

Person.objects.get_or_create(id=1)

Он будет автоматически обновляться, если существует, поскольку два данных с одним и тем же основным ключом не разрешены.

Ответ 6

Для всего лишь небольшого количества объектов update_or_create работает хорошо, но если вы делаете над большой коллекцией, он не будет хорошо масштабироваться. update_or_create всегда сначала запускает SELECT и после этого UPDATE.

for the_bar in bars:
    updated_rows = SomeModel.objects.filter(bar=the_bar).update(foo=100)
        if not updated_rows:
            # if not exists, create new
            SomeModel.objects.create(bar=the_bar, foo=100)

Это, в лучшем случае, будет запускать только первый запрос обновления, и только если он сопоставляет нулевые строки, запускает другой запрос INSERT. Это значительно увеличит вашу производительность, если вы ожидаете, что большая часть строк будет фактически существовать.

Однако все сводится к вашему варианту использования. Если вы ожидаете в основном вставки, возможно, может быть опция bulk_create().

Ответ 7

Я использовал метод create() для вставки строки в таблицу и метода filter(). Update() для обновления значений определенного поля в таблице. Но перед вызовом метода filter(). Update() я обновил объект, который имел значение таблицы перед вставкой строк, потому что после вставки строк размер объекта отличается. Таким образом, он не выдает ошибку! После завершения процесса httpresponse отправляется!