模型:
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不允许通过第一种方法保存值
Model:
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'The folloing does'nt save it to DB,
s=faqs.objects.filter(id=1) s[0].id=111 s[0].save()But this saves the upadted value to DB,
s=faqs.objects.filter(id=1)[0] s.id=111 s.save()Why is not django not allowing to save values via the first method
最满意答案
问题是每次切片查询集时,Django都会命中数据库并创建一个新实例。 因此,您设置id的实例与您调用save()实例不同 - 请记住Django实例没有标识,并且引用同一数据库行的单独对象不共享任何内容。
如果检查数据库查询,您可以看到发生了什么:您将看到第一行(过滤器)不执行任何查询。 对第二行执行SELECT - 但它只使用LIMIT 1获取一个实例。对第三行执行相同的SELECT,为您提供一个全新的实例。
你已经看到了这方面的一种方式。 另一种方法是强制整个查询集在filter后执行,但调用结果list 。
The issue is that each time you slice the queryset, Django hits the database and creates a new instance. So the instance you set the id on is not the same instance as the one you call save() on - remember that Django instances do not have identity, and that separate objects that refer to the same database row don't share anything.
You can see what's happening if you examine the database queries: you'll see that no queries are executed for the first line, the filter. A SELECT is executed for the second line - but it only gets one instance, using a LIMIT 1. And an identical SELECT is executed for the third line, giving you a completely new instance.
You've already seen one way round this. The other way is to force the entire queryset to be executed after the filter, but calling list on the result.
更多推荐
发布评论