在模型中,当创建外键字段时,Django显然会创建另一个具有相同字段名称后跟_id的字段。 例如,如果我有
class Post(models.Model):
user = models.ForeignKey(User,on_delete=models.CASCADE,default=None)
dated = models.DateTimeField(auto_now=True)
...
然后我将提供以下字段:
id,user,user_id,dated
我不确定为什么要添加此字段(user_id
)?
后来我想在类视图中覆盖我的queryset 所以我很困惑使用哪一个(用户字段或user_id字段) :
def get_queryset(self):
queryset = super().get_queryset()
return queryset.filter(user_id=self.request.user.id)
或者
def get_queryset(self):
queryset = super().get_queryset()
return queryset.filter(user=self.request.user.id)
我试过了两个,两个都很好用
我的问题是:
1)创建此附加字段的目的是什么?
2)原始外键字段(我的用户)和user_id字段之间有什么区别?
3)数据库中是否有user
和user_id
字段?有什么意义呢?
4)每条记录中user
和user_id
的内容是否相同?如果是这样,那么django自动创建的这个附加字段的目的是什么?
非常感谢
答案 0 :(得分:1)
Django只在数据库中为外键创建一个列。
字段与其生成的_id
属性之间的区别在于,访问该字段会对相关表中的完整列集执行查询,以构建完整的相关对象。如果你想要完整的对象,请使用该字段(也可能在初始查询中使用select_related()
来避免你进行N + 1次查询。)
另一方面,如果你需要的只是外键的DB级值,它通常是相关对象的主键(通常是你想要的),_id
属性快捷方式适合您,并且已经拥有数据,因为它实际上是外键列中的内容。
换句话说,假设我有这样的模型:
class ModelA(models.Model):
name = models.TextField()
class ModelB(models.Model):
name = models.TextField()
a_instance = models.ForeignKey(ModelA)
如果您查询ModelB
,例如ModelB.objects.get(pk=12)
,则会收到如下查询:
SELECT id, name, a_instance_id
FROM your_app.modelb
WHERE id = 12;
注意a_instance_id
是列的名称 - 它只是一个外键,它存储的所有内容都是指向ModelA
实例主键的指针。如果您只需要该主键,则访问a_instance_id
属性已经存在,而无需进行其他查询。但是,如果您访问a_instance
字段,则可以执行另一个查询:
SELECT id, name
FROM your_app.modela
WHERE id = (whatever the value of that foreign key was);