django按索引访问过滤器结果不会将其保存到模型中

时间:2012-08-07 08:32:09

标签: django django-models

型号:

class faqs(models.Model):
 id = models.AutoField(primary_key=True)
 question=models.TextField()
 answer=models.TextField()
 category=models.CharField(max_length=200,null=True)
 frequency=models.IntegerField(max_length=10, blank = True, null = True)
 class Meta:
    db_table='faqs'

下面的内容不会将其保存到DB,

s=faqs.objects.filter(id=1)
s[0].id=111
s[0].save()

但是这会将升级值保存到DB,

s=faqs.objects.filter(id=1)[0]
s.id=111
s.save()

为什么django不允许通过第一种方法保存值

2 个答案:

答案 0 :(得分:1)

问题是每次切片查询集时,Django都会访问数据库并创建一个 new 实例。因此,您设置id的实例与您调用save()的实例不同 - 请记住Django实例没有标识,并且引用相同数据库行的单独对象不要分享任何东西。

如果检查数据库查询,您可以看到发生了什么:您将看到没有对第一行(过滤器)执行查询。对第二行执行SELECT - 但它只使用LIMIT 1获得一个实例。对第三行执行相同的SELECT,为您提供一个全新的实例。

你已经看过这种方式了。另一种方法是强制整个查询集在filter之后执行,但在结果上调用list

答案 1 :(得分:-1)

可能因为QuerySets are lazy。这意味着当您从查询集访问项目而不启动它时,它不会更新查询集,因为它是queryset item而不是模型的真实实例。

修正:

s = faqs.objects.filter(id=1)
obj = s[0]
obj.id=111
obj.save()