Python Django模型-指定id而不是对象

Python Django模型-指定id而不是对象,python,django,django-models,Python,Django,Django Models,我很抱歉,如果我的问题被证明是愚蠢的,但我是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")

我很抱歉,如果我的问题被证明是愚蠢的,但我是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")
现在,当我尝试创建这样的对象时:

BlackListEntry.objects.create(user_banned=int(user_id),user_banning=int(banning_id))
我得到以下错误:

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)
BlackListEntry.objects.filter(user_banned__id=int(user_id),user_banning__id=int(banning_id))
一切正常。问题是:


我的解决方案是否命中数据库以检索两个用户,如果是,是否可以通过传递ID来避免它

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

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

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

另一种选择是缓存用户禁用和用户禁用对象


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

您的问题的答案是:是的

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

试试看:

BlackListEntry.objects.create(user_banned_id=int(user_id),user_banning_id=int(banning_id))
这是Django ORM生成的FK字段的默认名称模式。这样可以直接设置信息,避免查询

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

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)
BlackListEntry.objects.filter(user_banned__id=int(user_id),user_banning__id=int(banning_id))
这就是在Django QuerySet中访问属性的方式。带双下划线。然后可以与属性的值进行比较

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

您始终可以将
user\u banding
user\u banning
与实际的用户对象(而不是其ID)进行比较。但是,如果您还没有这些对象,那么这是没有用的


希望有帮助。

这给了我:“user\u banning\u id”是此函数的无效关键字参数。很抱歉,我刚刚意识到您正在创建对象。因此,您需要使用一个下划线进行访问。我将编辑我的答案来解释原因。谢谢,现在它起作用了。我想把你加上+1,但我太笨了,还不能这么做。没问题。很高兴这有帮助。