【问题标题】:How to define a default ForeignKey object in django using get_or_create?如何使用 get_or_create 在 django 中定义默认的 ForeignKey 对象?
【发布时间】:2016-03-31 18:26:41
【问题描述】:

我有两个想要关联的模型:用户和组。 每个用户都属于一个组。我尝试通过在 get_or_create() 中使用来创建默认用户:

group = models.ForeignKey(Group.objects.get_or_create(name="Free")[0])

但它会引发以下错误:

(fields.E300) 字段定义了与模型“组”的关系,该模型要么未安装,要么是抽象的。

我可以做些什么来解决这个问题?

每个用户都必须有一个非空组值。所以我读过这个 get_or_create() 方法。但我也看到它可以返回多个对象......我不希望它发生。我想过创建一个唯一的名称参数,但有更好的解决方案吗?

你能帮帮我吗?感谢您的帮助。

【问题讨论】:

  • 解释错误 - 不在函数内的代码,例如您问题中的行,在 Python 加载您的 models.py 文件后立即执行。这发生在 Django 进程启动的早期,当时 Django 在每个 INSTALLED_APPS 中查找 models.py 文件并导入它。问题是您还不知道还导入了哪些其他模型。这里的错误是因为Group模型(来自django.auth.models)还没有被导入,所以就好像它不存在一样(还)。
  • 正如其他人在答案中显示的那样,您可以将Group.objects.get_or_create(name="Free")[0] 放在一个函数中,这样它就不会立即执行,Django 只会在需要知道该值时才调用该函数。此时,您项目中的所有模型以及 Django 自己的模型都将被导入并且可以正常工作

标签: python django database


【解决方案1】:

可以在这里找到更全面的答案:How to set a Django model field's default value to a function call / callable (e.g., a date relative to the time of model object creation)

需要指定相关的Model并设置默认。

class User(models.Model):
    def default_group(self):
        return Group.objects.get_or_create(name="Free")[0]

    group = models.ForeignKey('app_name.Group', default=default_group)

您的默认值将在模型定义时进行评估,但 Django 允许您提供一个可调用的默认值,每次创建实例时都会调用它。

【讨论】:

  • 这对我来说似乎在运行迁移时失败了:TypeError: default_obj() missing 1 required positional argument: 'self'
【解决方案2】:

解释错误 - 不在函数内的代码,例如您问题中的行,在 Python 加载您的 models.py 文件后立即执行。这发生在 Django 进程启动的早期,当时 Django 在每个 INSTALLED_APPS 中查找 models.py 文件并导入它。问题是您还不知道还导入了哪些其他模型。这里的错误是因为Group模型(来自django.auth.models)还没有被导入,所以就好像它不存在一样(还)。

其他人建议您可以将Group.objects.get_or_create(name="Free")[0] 放在一个函数中,这样它就不会立即执行,Django 只会在需要知道该值时才调用该函数。此时,您项目中的所有模型以及 Django 自己的模型都已导入并且可以正常工作。

关于您问题的第二部分...是的,任何时候您使用 getget_or_create 方法都需要在 unique 字段上进行查询,否则您可能会收到 MultipleObjectsReturned 异常.

事实上,我认为你不应该使用get_or_create 来完成你在这里尝试做的事情。相反,您应该使用初始数据夹具:
https://docs.djangoproject.com/en/1.9/howto/initial-data/
...在您运行站点之前确保默认组已经存在(并且具有已知的主键值)。

这样您将知道默认Group 的唯一pk,您可以进行get 查询:

def default_group():
    return Group.objects.get(pk=1)

class YourModel(models.model):
    group = models.ForeignKey(Group, default=default_group)

【讨论】:

  • 我已经创建了它,并且当我通过管理屏幕创建了组时它可以工作。但是,当我删除数据库并再次对其进行测试时,它并没有起作用。似乎该组不是由夹具创建的。当我创建它时,它显示Installed 1 object(s) from 1 fixture(s) 但是当我在shell 上运行命令时,它返回一个空数组。 Group.objects.all() []。我不知道为什么。你有什么线索吗?
  • 查看数据库,看看夹具创建了什么
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-02-18
  • 2014-12-10
  • 2018-11-25
  • 2010-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多