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

T. *_*one 21 python django-models django-admin

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

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

created_by = models.ForeignKey(User, default=request.user)
Run Code Online (Sandbox Code Playgroud)

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

Dan*_*son 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) )
Run Code Online (Sandbox Code Playgroud)

  • 从Django 1.7开始,如果你正在使用Django的迁移,这个解决方案将不再适用,因为Django无法序列化lambdas.https://docs.djangoproject.com/en/1.7/topics/migrations/#serializing-values (35认同)
  • @EricRessler如何让它在Django 1.10中运行? (8认同)
  • @MadPhysicist 这种方法适用于更现代的 Django 版本:/sf/answers/495674371/ (2认同)

o_c*_*o_c 11

这是一个适用于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)
Run Code Online (Sandbox Code Playgroud)


Rah*_*ddy 10

对于django 1.7或更高,

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

例如,

created_by = models.ForeignKey(User, default=1)
Run Code Online (Sandbox Code Playgroud)


Max*_*ysh 7

我做这个类似于@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)
Run Code Online (Sandbox Code Playgroud)


Ste*_*eef 5

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