[英]How can I update the field value of all objects in a queryset in Django?
[英]How to update queryset value in django?
我在我的項目中編寫了一個python腳本。 我想更新字段的值。
這是我的模式
class News_Channel(models.Model):
name = models.TextField(blank=False)
info = models.TextField(blank=False)
image = models.FileField()
website = models.TextField()
total_star = models.PositiveIntegerField(default=0)
total_user = models.IntegerField()
class Meta:
ordering = ["-id"]
def __str__(self):
return self.name
class Count(models.Model):
userId = models.ForeignKey(User, on_delete=models.CASCADE)
channelId = models.ForeignKey(News_Channel, on_delete=models.CASCADE)
rate = models.PositiveIntegerField(default=0)
def __str__(self):
return self.channelId.name
class Meta:
ordering = ["-id"]
這是我的python腳本:
from feed.models import Count, News_Channel
def run():
for i in range(1, 11):
news_channel = Count.objects.filter(channelId=i)
total_rate = 0
for rate in news_channel:
total_rate += rate.rate
print(total_rate)
object = News_Channel.objects.filter(id=i)
print(total_rate)
print("before",object[0].total_star,total_rate)
object[0].total_star = total_rate
print("after", object[0].total_star)
object.update()
從Count表中計算total_rate后,我想更新News_Channel表中的總星值。 我沒有這樣做,並在更新之前和更新之后獲取數據為零。 雖然total_rate有價值。
為什么失敗的原因是因為這里object
是一個QuerySet
的News_Channel
S,是啊是QuerySet
可能只包含一個News_Channel
,但是這是無關緊要的。
如果然后使用object[0]
,則向數據庫進行查詢以獲取第一個元素並將其反序列化為News_Channel
對象。 然后設置該對象的total_star
,但永遠不保存該對象。 您只在整個查詢集上調用.update()
,從而產生另一個獨立查詢。
你可以解決這個問題:
objects = News_Channel.objects.filter(id=i)
object = objects[0]
object.total_star = total_rate
object.save()
或者,鑒於您不需要任何驗證,您可以通過以下方式提高性能:
News_Channel.objects.filter(id=i).update(total_star=total_rate)
News_Channel
如果要更新所有 News_Channel
,實際上最好使用Subquery
:
from django.db.models import OuterRef, Sum, Subquery
subq = Subquery(
Count.objects.filter(
channelId=OuterRef('id')
).annotate(
total_rate=Sum('rate')
).order_by('channelId').values('total_rate')[:1]
)
News_Channel.objects.update(total_star=subq)
原因是您的情況下的object
是一個查詢集,在您嘗試更新object[0]
,您不會將結果存儲在數據庫中,也不會刷新查詢集。 要使其工作,您應該將要更新的字段傳遞給更新方法。
所以,試試這個:
def run():
for i in range(1, 11):
news_channel = Count.objects.filter(channelId=i)
total_rate = 0
for rate in news_channel:
total_rate += rate.rate
print(total_rate)
object = News_Channel.objects.filter(id=i)
print(total_rate)
print("before",object[0].total_star,total_rate)
object.update(total_star=total_rate)
print("after", object[0].total_star)
可以使用聚合來計算News_Channel.total_star
news_channel_obj.count_set.aggregate(total_star=Sum('rate'))['total_star']
然后,您可以在腳本中使用它:
object.total_star = object.count_set.aggregate(total_star=Sum('rate'))['total_star']
或者,如果您不需要緩存此值,因為性能不是問題,您可以刪除total_star字段並將其添加為News_Channel
模型上的屬性
@property
def total_star(self):
return self.count_set.aggregate(total_star=Sum('rate'))['total_star']
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.