如何使用get_or_create在django中定义默认的ForeignKey对象?

时间:2022-02-03 08:34:22

I have two models which I want to relate: User and Group. Each user belongs to a group. I've tried to create a default user by using in get_or_create():

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

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

But it raises the following error:

但它引发了以下错误:

(fields.E300) Field defines a relation with model 'Group', which is either not installed, or is abstract.

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

What can I do to fix this issue?

我该怎么做才能解决这个问题?

Each user must have a non-null group value. So I've read about this get_or_create() method. But I've also seen that it can return more than one object... and I don't want it to happen. I thought about creating a unique name parameter but is there a better solution for it?

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

Can you help me, please? I appreciate your help.

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

2 个解决方案

#1


2  

A more comprehensive answer can be found here: 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)

可以在这里找到更全面的答案:如何将Django模型字段的默认值设置为函数调用/可调用(例如,相对于模型对象创建时间的日期)

You need to specifify the related Model and set the default.

您需要指定相关的模型并设置默认值。

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)

Your default value would be evaluated at model definition time, but Django allows you to provide a callable as default, which is called for each instance creation.

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

#2


1  

To explain the error - code that is not inside a function, such as the line in your question, is executed as soon as your models.py file is loaded by Python. This happens early in the start-up of your Django process, when Django looks for a models.py file in each of the INSTALLED_APPS and imports it. The problem is that you don't know which other models have been imported yet. The error here is because the Group model (from django.auth.models) has not been imported yet, so it is as if it doesn't exist (yet).

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

Others have suggested you could put the Group.objects.get_or_create(name="Free")[0] in a function so that it is not executed immediately, Django will instead call the function only when it needs to know the value. At this point all the models in your project, and Django's own models, will have been imported and it will work.

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

Regarding the second part of your question... yes, any time you use get or get_or_create methods you need to query on a unique field otherwise you may get MultipleObjectsReturned exception.

关于你问题的第二部分......是的,每当你使用get或get_or_create方法时,你需要在一个唯一的字段上查询,否则你可能会得到MultipleObjectsReturned异常。

In fact I think you should not use get_or_create for what you are trying to do here. Instead you should use an initial data fixture:
https://docs.djangoproject.com/en/1.9/howto/initial-data/
...to ensure that the default group already exists (and with a known primary key value) before you run your site.

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

That way you will know the unique pk of the default Group and you can do a get query:

这样你就会知道默认组的唯一pk,你可以进行获取查询:

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

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

#1


2  

A more comprehensive answer can be found here: 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)

可以在这里找到更全面的答案:如何将Django模型字段的默认值设置为函数调用/可调用(例如,相对于模型对象创建时间的日期)

You need to specifify the related Model and set the default.

您需要指定相关的模型并设置默认值。

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)

Your default value would be evaluated at model definition time, but Django allows you to provide a callable as default, which is called for each instance creation.

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

#2


1  

To explain the error - code that is not inside a function, such as the line in your question, is executed as soon as your models.py file is loaded by Python. This happens early in the start-up of your Django process, when Django looks for a models.py file in each of the INSTALLED_APPS and imports it. The problem is that you don't know which other models have been imported yet. The error here is because the Group model (from django.auth.models) has not been imported yet, so it is as if it doesn't exist (yet).

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

Others have suggested you could put the Group.objects.get_or_create(name="Free")[0] in a function so that it is not executed immediately, Django will instead call the function only when it needs to know the value. At this point all the models in your project, and Django's own models, will have been imported and it will work.

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

Regarding the second part of your question... yes, any time you use get or get_or_create methods you need to query on a unique field otherwise you may get MultipleObjectsReturned exception.

关于你问题的第二部分......是的,每当你使用get或get_or_create方法时,你需要在一个唯一的字段上查询,否则你可能会得到MultipleObjectsReturned异常。

In fact I think you should not use get_or_create for what you are trying to do here. Instead you should use an initial data fixture:
https://docs.djangoproject.com/en/1.9/howto/initial-data/
...to ensure that the default group already exists (and with a known primary key value) before you run your site.

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

That way you will know the unique pk of the default Group and you can do a get query:

这样你就会知道默认组的唯一pk,你可以进行获取查询:

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

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