Django - 外键必须是一个实例

Pyt*_*ast 6 django django-models

我有一个模特

from django.contrib.auth.models import User

class ModelA(models.Model):
    phone = models.CharField(max_length=20)
    user = models.ForeignKey(User)
Run Code Online (Sandbox Code Playgroud)

我需要将数据插入此模型中.我有一个端点托管,它提供了以下数据{'phone':XXXXXXXX, 'user_id':123}.

现在,当我将数据插入此模型时

obj = ModelA.objects.create(phone=data['phone'], user = data['user_id]
Run Code Online (Sandbox Code Playgroud)

它抛出一个错误说

Cannot assign "u'123'": "ModelA.user" must be a "User" instance.
Run Code Online (Sandbox Code Playgroud)

同意,因为因为使用django orm,你可以根据对象而不是数字进行交互.因此,我首先找到了User的对象,然后创建了ModelA对象.

user_obj = User.objects.get(id=data['id']
modelobj = ModelA.objects.create(phone=data['phone'], user = user_obj
Run Code Online (Sandbox Code Playgroud)

直到这里一切正常.

现在,我的问题是,是否存在ModelA使用user_idUser对象直接分配/创建对象的任何其他方式,因为它首先涉及查询用户模型然后插入.它就像创建的每个ModelA对象的额外读取操作.

Vla*_*yga 8

从我的历史评论中可以看出,接受的答案并不正确.所以@yekta要求我重新提交我的意见:

要创建父模型,请使用整数值,如:

ModelA.objects.create(phone=data['phone'], user_id=1)
Run Code Online (Sandbox Code Playgroud)


lul*_*lis 5

(我一直在为一个错误的答案获得投票.如果你使用的数据库有实际的完整性检查,你可以使用attr_name _id来插入相关的对象.

希望我能删除它.看下面的答案.)

基本上,你不能这样做.Django的ORM期待一个对象而不仅仅是一个密钥.这是为了在应用程序级别而不是数据库级别检查完整性的额外抽象层而付出的代价.

如果性能是一个问题(并且在一般情况下不是),则可以使User对象的读取操作尽可能轻.该only函数将返回一个对象的查询集,强制select只检索id列,该列肯定是索引的.

user = User.objects.only('id').get(id=data['user_id'])
obj = ModelA.objects.create(phone=data['phone'], user=user)
Run Code Online (Sandbox Code Playgroud)

  • 不完全正确,只是对于将要阅读此问题的未来人有一种方法,你可以做`ModelA.objects.create(phone = data ['phone'],user = user_id)#in caseA与用户相关通过用户ID,对于其他字段,您可以执行user_name` (2认同)
  • 正确的代码是:ModelA.objects.create(phone = data ['phone'],user_id = 1) (2认同)