10

Djangoアプリのユーザー向けのさまざまな構成オプションを含むStaffSettingsというDjangoモデルがあります。各ユーザーは、StaffSettingsテーブルに最大で1つのエントリを持ちます。

1つの設定がdefault_year_levelであり、次のようなユーザーオブジェクトのコードがあるとします。

def set_default_year_level(u, year_level):
    obj, _created = StaffSettings.objects.get_or_create(user=u)
    obj.default_year_level = year_level
    obj.save()

一般的なユースケースのように見えるので、関数の本体を1行に収めることをお勧めしますが、次のように定義した場合

def set_default_year_level(u, year_level):
    StaffSettings.objects.filter(user=u).update(default_year_level=year_level)

これは、問題のユーザーがすでにStaffSettingsテーブルに行を持っている場合は正常に機能しますが、存在しない場合は関連する行を作成しません。

これをコーディングするための慣用的/最良の方法は何ですか?(たとえば、ある種のfilter_or_create関数はありますか?または他の人はこのイディオムを処理するためにデコレータ/ヘルパー関数を作成しますか?)

4

2 に答える 2

6

最初の関数に問題はありません。このユースケースでも同じように記述します。

ただし、モデルの多くのフィールドで同じ機能が必要で、繰り返したくない場合は、フィールドをパラメーターとして渡すことができます。

def set_default_value(u, field, value):
  obj, _created = StaffSettings.objects.get_or_create(user=u)
  setattr(obj, field, value)
  obj.save()

また、 update()関数は一度に複数のオブジェクトを更新することを目的としており、save()メソッドやモデルのシグナルをトリガーしないため、とにかくupdate()関数には近づきません(https://docs.djangoproject.com/enを参照)。 / dev / topics / db / queries /#updating-multiple-objects-at-once

于 2013-03-18T09:20:44.057 に答える
6

Django 1.7以降、次のものを使用できますupdate_or_create()

def set_default_year_level(u, year_level):
    obj, _created = StaffSettings.objects.update_or_create(
        user=u,
        default_year_level=year_level
    )

または、前の回答で説明したより一般的なケースの場合:

def set_default_values(u, **kwargs):
    obj, _created = StaffSettings.objects.update_or_create(user=u, defaults=kwargs)

これはまたあなたの追加の要件を達成します

関数の本体を1行に収めたい

于 2016-10-17T10:33:18.643 に答える