如何为Django ForeignKey Model或AdminModel字段指定默认值?

时间:2022-03-28 02:16:57

How can I set a default value on a ForeignKey field in a django Model or AdminModel?

如何在django Model或AdminModel中的ForeignKey字段上设置默认值?

Something like this (but of course this doesn't work)...

像这样的东西(但当然这不起作用)......

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

I know I can 'trick' it in the view, but in terms of the AdminModel it doesn't seem possible.

我知道我可以在视图中“欺骗”它,但就AdminModel而言,似乎不可能。

10 个解决方案

#1


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) )

#2


Here's a solution that will work in Django 1.7. Instead of providing the default at the field definition, set it as null-able, but overide the 'save' function to fill it on the first time (while it's null):

这是一个适用于Django 1.7的解决方案。不是在字段定义中提供默认值,而是将其设置为null-able,但是在“save”函数上覆盖第一次填充它(当它为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)

#3


For django 1.7 or greater,

对于django 1.7或更高,

Just create an ForeignKey object and save it. "default" value can be the id of the the object that should be linked by default.

只需创建一个ForeignKey对象并保存即可。 “default”值可以是默认情况下应链接的对象的id。

For example,

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

#4


If you are using the development version of Django, you can implement the formfield_for_foreignkey() method on your AdminModel to set a default value.

如果您使用的是Django的开发版本,则可以在AdminModel上实现formfield_for_foreignkey()方法来设置默认值。

#5


I've done this similarly to @o_c, but I'd rather use get_or_create than just plain pk.

我这样做与@o_c类似,但我宁愿使用get_or_create而不仅仅是普通的pk。

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)

#6


def get_user_default_id():
    return 1

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

#7


As for me, for Django 1.7 its work, just pk:

至于我,对于Django 1.7它的工作,只是pk:

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

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

but remember, that migration looks like

但请记住,迁移看起来像

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

so, i don't think it's to be working with dynamic user pk.

所以,我不认为这是与动态用户pk合作。

#8


This is a slight modification to the answer from o_c. It should save you one hit on the database. Notice in the save method I use self.a_id = 1 instead of self.a = Foo.objects.get(id=1). It has the same effect without having to query Foo.

这是对o_c答案的略微修改。它应该为您节省数据库的一击。请注意,在save方法中,我使用self.a_id = 1而不是self.a = Foo.objects.get(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)

#9


For Django >= 1.7, you can set the default for a ForeignKey field in two different ways:

对于Django> = 1.7,您可以通过两种不同的方式设置ForeignKey字段的默认值:

1) Directly as an integer

1)直接作为整数

DEFAULT_CREATED_BY_USER = 42

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

2) As a nonlambda callable returning an integer

2)作为nonlambda可调用返回一个整数

You can also use a callable that can be resolved to a full module path. This means that lambdas does not work. But this will:

您还可以使用可解析为完整模块路径的可调用对象。这意味着lambda不起作用。但这会:

def default_created_by_user():
    return 42

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

References:

#10


class table1(models.Model):
    id = models.AutoField(primary_key=True)
    agentname = models.CharField(max_length=20)

class table1(models.Model):
    id = models.AutoField(primary_key=True)
    lastname = models.CharField(max_length=20)
    table1 = models.ForeignKey(Property)

#1


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) )

#2


Here's a solution that will work in Django 1.7. Instead of providing the default at the field definition, set it as null-able, but overide the 'save' function to fill it on the first time (while it's null):

这是一个适用于Django 1.7的解决方案。不是在字段定义中提供默认值,而是将其设置为null-able,但是在“save”函数上覆盖第一次填充它(当它为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)

#3


For django 1.7 or greater,

对于django 1.7或更高,

Just create an ForeignKey object and save it. "default" value can be the id of the the object that should be linked by default.

只需创建一个ForeignKey对象并保存即可。 “default”值可以是默认情况下应链接的对象的id。

For example,

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

#4


If you are using the development version of Django, you can implement the formfield_for_foreignkey() method on your AdminModel to set a default value.

如果您使用的是Django的开发版本,则可以在AdminModel上实现formfield_for_foreignkey()方法来设置默认值。

#5


I've done this similarly to @o_c, but I'd rather use get_or_create than just plain pk.

我这样做与@o_c类似,但我宁愿使用get_or_create而不仅仅是普通的pk。

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)

#6


def get_user_default_id():
    return 1

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

#7


As for me, for Django 1.7 its work, just pk:

至于我,对于Django 1.7它的工作,只是pk:

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

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

but remember, that migration looks like

但请记住,迁移看起来像

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

so, i don't think it's to be working with dynamic user pk.

所以,我不认为这是与动态用户pk合作。

#8


This is a slight modification to the answer from o_c. It should save you one hit on the database. Notice in the save method I use self.a_id = 1 instead of self.a = Foo.objects.get(id=1). It has the same effect without having to query Foo.

这是对o_c答案的略微修改。它应该为您节省数据库的一击。请注意,在save方法中,我使用self.a_id = 1而不是self.a = Foo.objects.get(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)

#9


For Django >= 1.7, you can set the default for a ForeignKey field in two different ways:

对于Django> = 1.7,您可以通过两种不同的方式设置ForeignKey字段的默认值:

1) Directly as an integer

1)直接作为整数

DEFAULT_CREATED_BY_USER = 42

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

2) As a nonlambda callable returning an integer

2)作为nonlambda可调用返回一个整数

You can also use a callable that can be resolved to a full module path. This means that lambdas does not work. But this will:

您还可以使用可解析为完整模块路径的可调用对象。这意味着lambda不起作用。但这会:

def default_created_by_user():
    return 42

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

References:

#10


class table1(models.Model):
    id = models.AutoField(primary_key=True)
    agentname = models.CharField(max_length=20)

class table1(models.Model):
    id = models.AutoField(primary_key=True)
    lastname = models.CharField(max_length=20)
    table1 = models.ForeignKey(Property)