web-dev-qa-db-ja.com

Djangoモデルを作成するか、存在する場合は更新します

個人のIDが存在しない場合は、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

しかし、既存の人物オブジェクトを確認して取得する場所がわかりません。

93
user1687717

「存在する場合は更新する」を使用する場合は、「 @ 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
145
bakkal

あなたの質問が get_or_create メソッド(少なくともDjango 1.3から利用可能)を求めているのか、 pdate_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}
)
147
Zags

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
9
Aamir Adnan

質問のタイトルは、質問の本文で説明されているように取得または作成するのではなく、作成または更新する方法を尋ねているように見えるので、答えを追加すると思います。

オブジェクトを作成または更新したい場合、.save()メソッドは既に the docs からデフォルトでこの動作をしています。

Djangoは、INSERTまたはUPDATE SQLステートメントを使用する必要性を抽象化します。具体的には、save()を呼び出すと、Djangoはこのアルゴリズムに従います。

オブジェクトの主キー属性がTrueと評価される値(つまり、Noneまたは空の文字列以外の値)に設定されている場合、DjangoはUPDATEを実行します。オブジェクトの主キー属性が設定されていない場合、またはUPDATEが何も更新しなかった場合、DjangoはINSERTを実行します。

「UPDATEが何も更新しなかった場合」と言うとき、それらは基本的に、オブジェクトに指定したIDがデータベースにまだ存在しない場合を指していることに注意してください。

3
Tom Manterfield

少量のオブジェクトの場合、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)

これは、せいぜい最初のupdate-queryのみを実行し、ゼロ行に一致した場合のみ、別のINSERT-queryを実行します。ほとんどの行が実際に存在すると予想される場合、パフォーマンスが大幅に向上します。

それはすべてあなたのユースケースに帰着します。ほとんどの場合、挿入を期待している場合は、おそらく bulk_create() コマンドがオプションになる可能性があります。

1

作成時の入力の1つが主キーである場合、これで十分です。

Person.objects.get_or_create(id=1)

同じ主キーを持つ2つのデータは許可されないため、存在する場合は自動的に更新されます。

1
Aminah Nuraini