如何在 django 模型或 AdminModel 中的 ForeignKey 字段上设置默认值?
像这样的东西(但当然这不起作用)......
created_by = models.ForeignKey(User, default=request.user)
我知道我可以在视图中“欺骗”它,但就 AdminModel 而言,这似乎是不可能的。
如何在 django 模型或 AdminModel 中的 ForeignKey 字段上设置默认值?
像这样的东西(但当然这不起作用)......
created_by = models.ForeignKey(User, default=request.user)
我知道我可以在视图中“欺骗”它,但就 AdminModel 而言,这似乎是不可能的。
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) )
对于 django 1.7 或更高版本,
只需创建一个 ForeignKey 对象并保存它。“默认”值可以是默认链接的对象的 ID。
例如,
created_by = models.ForeignKey(User, default=1)
这是一个适用于 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)
我的做法与@o_c 类似,但我宁愿使用get_or_create
而不仅仅是 plain 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)
如果你使用的是 Django 的开发版本,你可以实现你的formfield_for_foreignkey()
方法AdminModel
来设置一个默认值。
至于我,对于 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 一起工作。
这是对o_c答案的轻微修改。它应该可以为您节省一击数据库。请注意,在保存方法中,我使用 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)
对于 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 可调用对象
您还可以使用可解析为完整模块路径的可调用对象。这意味着 lambdas 不起作用。但这将:
def default_created_by_user():
return 42
class MyModel(Model):
created_by = models.ForeignKey(User, default=default_created_by_user)
参考:
def get_user_default_id():
return 1
created_by = models.ForeignKey(User, default=get_user_default_id)
在寻找更好解决方案的所有迭代中,我发现创建一个小函数将大大解决任务的复杂性。因为一些解决方案在较新的 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)
您应该在 settings.py 文件中有与 setting.AUTH_USER_MODEL 相关的设置。
您可以查看以下文档:
“ https://docs.djangoproject.com/en/1.10/topics/auth/customizing/#substituting-a-custom-user-model ”
使用偏函数代替 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 ))
您可以覆盖模型管理员的get_form方法。
管理员.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)
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)