而不是分配djobango id

2024-10-01 13:39:11 发布

您现在位置:Python中文网/ 问答频道 /正文

如果我的问题被证明是愚蠢的,我道歉,但我对Django相当陌生,我在任何地方都找不到答案。在

我有以下型号:

class BlackListEntry(models.Model):
  user_banned = models.ForeignKey(auth.models.User,related_name="user_banned")
  user_banning = models.ForeignKey(auth.models.User,related_name="user_banning")

现在,当我尝试创建这样的对象时:

^{pr2}$

我得到以下错误:

Cannot assign "1": "BlackListEntry.user_banned" must be a "User" instance.

当然,如果我换成这样:

user_banned = User.objects.get(pk=user_id)
user_banning = User.objects.get(pk=banning_id)
BlackListEntry.objects.create(user_banned=user_banned,user_banning=user_banning)

一切正常。问题是:

我的解决方案是否会访问数据库以检索两个用户,如果是,是否可以避免它,只传递id?在


Tags: name证明authidgetobjectsmodelsrelated
2条回答

我相信当你获取用户时,它会击中数据库。。。在

为了避免这种情况,您必须编写原始sql来使用下面描述的方法进行更新:

https://docs.djangoproject.com/en/dev/topics/db/sql/

如果您决定这样做,请记住,您有责任保护自己免受sql注入攻击。在

另一种选择是缓存用户禁止和用户禁止的对象。在

但是很有可能,简单地抓住用户并创建BlackListEntry不会给您带来任何明显的性能问题。缓存或执行原始sql只会带来一点好处。在这成为问题之前,你可能会遇到其他问题。在

你的问题的答案是:是的。在

Django将访问数据库(至少)3次,2次检索两个用户对象,第3次访问提交所需的信息。这将导致绝对不必要的开销。在

试试看:

BlackListEntry.objects.create(user_banned_id=int(user_id),user_banning_id=int(banning_id))

这是Django ORM生成的FK字段的默认名称模式。这样可以直接设置信息,避免查询。在

如果要查询已保存的BlackListEntry对象,可以使用双下划线导航属性,如下所示:

^{pr2}$

这就是访问Django querysets中属性的方法。带双下划线。然后可以与属性的值进行比较。在

虽然非常相似,但它们的工作方式完全不同。第一个属性直接设置一个属性,而第二个属性由django解析,它在''uuuu'处拆分,并以正确的方式查询数据库,第二部分是属性的名称。在

您可以始终将user_banned和{}与实际用户对象进行比较,而不是它们的id。但是如果你没有随身携带这些物品,这是没有用的。在

希望有帮助。在

相关问题 更多 >