Python 如何为Django ForeignKey模型或AdminModel字段指定默认值?
如何在django模型或AdminModel中设置ForeignKey字段的默认值 像这样的东西(当然这不起作用)Python 如何为Django ForeignKey模型或AdminModel字段指定默认值?,python,django-models,django-admin,Python,Django Models,Django Admin,如何在django模型或AdminModel中设置ForeignKey字段的默认值 像这样的东西(当然这不起作用) 我知道我可以在视图中“欺骗”它,但就AdminModel而言,这似乎是不可能的。如果您使用的是Django的开发版本,您可以在您的AdminModel上实现该方法来设置默认值。至于我,对于Django 1.7的工作,只需pk: class Foo(models.Model): a = models.CharField(max_length=42) class Bar(mo
我知道我可以在视图中“欺骗”它,但就AdminModel而言,这似乎是不可能的。如果您使用的是Django的开发版本,您可以在您的
AdminModel上实现该方法来设置默认值。至于我,对于Django 1.7的工作,只需pk:
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) )
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。这里有一个在Django 1.7中适用的解决方案。
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)
与其在字段定义中提供默认值,不如将其设置为null-able,但要覆盖“save”函数以在第一次填充它(当它为null时):
我这样做与@o_c类似,但我更愿意使用get_或
而不是简单的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)
这是对来自的答案的轻微修改。它应该能帮你在数据库上省下一笔钱。注意,在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)
对于django 1.7或更高版本
只需创建一个ForeignKey对象并保存它。“default”值可以是默认情况下应该链接的对象的id
比如说,
created_by = models.ForeignKey(User, default=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可调用
DEFAULT_CREATED_BY_USER = 42
class MyModel(Model):
created_by = models.ForeignKey(User, default=DEFAULT_CREATED_BY_USER)
您还可以使用可调用函数,该函数可以解析为完整的模块路径。这意味着lambdas不起作用。但这将:
def default_created_by_user():
return 42
class MyModel(Model):
created_by = models.ForeignKey(User, default=default_created_by_user)
参考资料:
- (django文件)
- (为什么lambdas会失败)
使用部分函数代替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 ))
您应该在settings.py文件中具有与setting.AUTH\u USER\u MODEL相关的设置
您可以查看以下文档:
“”您可以覆盖模型管理员的方法
管理员
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)
为了找到更好的解决方案,我一直在迭代,但我发现创建一个小函数将在很大程度上解决任务的复杂性。因为一些解决方案已经过时,或者在较新的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)
你和这篇文章的作者是同一个人吗?如果没有,请考虑添加链接。在模型中使用符号名作为默认值是非常常见的用法。我不记得该站点,但将代码段更改为较短的模式。从Django 1.7开始,如果使用Django的迁移,此解决方案将不再有效,因为Django无法序列化lambda@EricRessler如何让它在Django 1.10中工作?@MadPhysician这种方法在更现代的Django版本中工作:请给代码添加一些解释,为什么这能回答这个问题?添加一些描述。你真的需要让字段为空吗?我认为,该对象还没有保存,即它还没有id,它还没有被“清理”,除非你在超链接前加上“完全清理”(…save..因此我将条件更改为if self.id为None:并且在不使用null=True的情况下应该可以工作。@MilanoSlesarik您可能是对的。我之所以将它放在那里,首先是因为它是我添加到现有模型(具有现有记录行)中的一个新字段,所以我必须允许它为null。@o_c作为save(..)不是一个好主意不是从批处理更新查询集调用的。除非您显式循环每个返回的项并调用save,否则这将首先破坏使用批处理更新的目的(开发人员往往会忘记)。这个答案应该更高,因为它简单而聪明。未解析的引用“请求”
。您如何在这里传递请求?;)Django在2009年是否有AdminModel
?我想没有。您的意思是ModelAdmin
?
def get_request_user():
# or any complex query result to set default value in ForeignKey
return request.user.id
created_by = models.ForeignKey(User, default=get_request_user)