web-dev-qa-db-ja.com

Django ForeignKey ModelまたはAdminModelフィールドのデフォルトをどのように指定しますか?

Django ModelまたはAdminModelのForeignKeyフィールドにデフォルト値を設定するにはどうすればよいですか?

このようなもの(もちろんこれは機能しません)...

created_by = models.ForeignKey(User, default=request.user)

私はそれをビューで「だます」ことができることを知っていますが、AdminModelの観点からは可能ではないようです。

23
T. Stone
class Foo(models.Model):
    a = models.CharField(max_length=42)

class Bar(models.Model):
    b = models.CharField(max_length=42)
    a = models.ForeignKey(Foo, default=lambda: Foo.objects.get(id=1) )
29

Django 1.7以上の場合、

ForeignKeyオブジェクトを作成して保存するだけです。 「デフォルト」の値には、デフォルトでリンクするオブジェクトのIDを指定できます。

例えば、

created_by = models.ForeignKey(User, default=1)
13

Django 1.7で機能するソリューションを次に示します。フィールド定義でデフォルトを提供する代わりに、それをnull可能として設定しますが、「保存」関数をオーバーライドして、最初にそれを埋めます(それがnullの場合):

class Foo(models.Model):
    a = models.CharField(max_length=42)

class Bar(models.Model):
    b = models.CharField(max_length=42)
    a = models.ForeignKey(Foo, null=True)

    def save(self, *args, **kwargs):
        if self.a is None:  # Set default reference
            self.a = Foo.objects.get(id=1)
        super(Bar, self).save(*args, **kwargs)
11
o_c

Djangoの開発バージョンを使用している場合、_ formfield_for_foreignkey() メソッドをAdminModelに実装してデフォルト値を設定できます。

5
Steef

@o_cと同様にこれを行いましたが、単なるpkではなくget_or_createを使用します。

class UserSettings(models.Model):
    name = models.CharField(max_length=64, unique=True)
    # ... some other fields 

    @staticmethod
    def get_default_user_settings():
        user_settings, created = UserSettings.objects.get_or_create(
            name = 'Default settings'
        )
        return user_settings

class SiteUser(...):
    # ... some other fields

    user_settings = models.ForeignKey(
        to=UserSettings, 
        on_delete=models.SET_NULL, 
        null=True
    )

    def save(self, *args, **kwargs):
        if self.user_settings is None:
            self.user_settings = UserSettings.get_default_params()
        super(SiteUser, self).save(*args, **kwargs)
4
Max Malysh
def get_user_default_id():
    return 1

created_by = models.ForeignKey(User, default=get_user_default_id)
1
Philippos

私に関しては、Django= 1.7の場合、pk:

category = models.ForeignKey(Category, editable=False, default=1)

ただし、移行は次のようになります。

migrations.AlterField(
            model_name='item',
            name='category',
            field=models.ForeignKey(default=1, editable=False, to='item.Category'),
            preserve_default=True,
        ),

だから、それは動的なユーザーpkで作業することだとは思わない。

1
LennyLip

Django> = 1.7の場合、ForeignKeyフィールドのデフォルトを2つの異なる方法で設定できます。

1)整数として直接

DEFAULT_CREATED_BY_USER = 42

class MyModel(Model):
    created_by = models.ForeignKey(User, default=DEFAULT_CREATED_BY_USER)

2)整数を返す非ラムダ呼び出し可能として

また、完全なモジュールパスに解決できる呼び出し可能オブジェクトを使用することもできます。つまり、ラムダは機能しません。しかし、これは:

def default_created_by_user():
    return 42

class MyModel(Model):
    created_by = models.ForeignKey(User, default=default_created_by_user)

参照:

1
Rune Kaagaard

これは o_c からの回答を少し変更したものです。データベースへのヒットが1つ減るはずです。 saveメソッドでは、self.a = Foo.objects.get(id = 1)の代わりにself.a_id = 1を使用していることに注意してください。 Fooをクエリしなくても同じ効果があります。

class Foo(models.Model):
    a = models.CharField(max_length=42)

class Bar(models.Model):
    b = models.CharField(max_length=42)
    a = models.ForeignKey(Foo, null=True)

    def save(self, *args, **kwargs):
        if self.a is None:  # Set default reference
            self.a_id = 1
        super(Bar, self).save(*args, **kwargs)
1
Andrew Simpson

ラムダ関数の代わりに部分関数を使用します。 Lambda関数はシリアル化されていないため、移行時にエラーが発生します。

class Foo(models.Model):
    a = models.CharField(max_length=42)

class Bar(models.Model):
    b = models.CharField(max_length=42)
    a = models.ForeignKey(Foo, default=partial(Foo.objects.get, id=1 ))
0
Kedar Jathar

Settings.pyファイルには、setting.AUTH_USER_MODELに関連する設定が必要です。

あなたは以下の文書を見ることができます:

" https://docs.djangoproject.com/en/1.10/topics/auth/customizing/#substituting-a-custom-user-model "

0
vikasvmads

より良い解決策を見つけるためのすべての反復の中で、小さな関数を作成すると、タスクの複雑さが大幅に解決されることがわかりました。一部のソリューションが古いか、または新しいDjangoバージョンでサポートされているためです。

def get_request_user():
    # or any complex query result to set default value in ForeignKey
    return request.user.id

次に、上記の関数をForeignKeyの引数として渡すことができます。

created_by = models.ForeignKey(User, default=get_request_user)
0
nishit chittora

モデル管理者の get_form メソッドをオーバーライドできます。

admin.py

class YourModelAdmin(admin.ModelAdmin):
    def get_form(self, request, obj=None, **kwargs):
        form = super(YourModelAdmin, self).get_form(request, obj, **kwargs)
        form.base_fields['created_by'].initial = request.user
    return form

admin.site.register(YourModel, YourModelAdmin)
0
Anusha Prasanth