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

时间:2009-06-02 04:56:30

标签: python django-models django-admin

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

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

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

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

14 个答案:

答案 0 :(得分:30)

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

答案 1 :(得分:11)

这是一个适用于Django 1.7的解决方案。 不是在字段定义中提供默认值,而是将其设置为无效,但是除了“保存”之外。函数在第一次填充它(当它为空时):

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)

答案 2 :(得分:7)

对于django 1.7或更高版本,

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

例如,

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

答案 3 :(得分:5)

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

答案 4 :(得分:4)

我这样做与@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)

答案 5 :(得分:1)

至于我,对于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合作。

答案 6 :(得分:1)

def get_user_default_id():
    return 1

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

答案 7 :(得分:1)

这是对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)

答案 8 :(得分:1)

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

1)直接作为整数

DEFAULT_CREATED_BY_USER = 42

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

2)作为非lambda可调用项,返回整数

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

def default_created_by_user():
    return 42

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

参考文献:

答案 9 :(得分:0)

使用lambda函数代替lambda函数。 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 ))

答案 10 :(得分:0)

您应该在settings.py文件中具有与setting.AUTH_USER_MODEL相关的设置。

您可以在下面的文档中查找:

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

答案 11 :(得分:0)

您可以覆盖模型管理员的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)

答案 12 :(得分:0)

在寻找更好的解决方案的所有迭代过程中,我发现创建一个小的函数将实质上解决任务的复杂性。因为某些解决方案已在较新的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)

答案 13 :(得分:-2)

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)