ims*_*ful 4 python django django-models django-queryset
我在我的项目中编写了一个 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"]
Run Code Online (Sandbox Code Playgroud)
这是我的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()
Run Code Online (Sandbox Code Playgroud)
从 Count 表计算 total_rate 后,我想更新 News_Channel 表中的总星级值。我没有这样做并且将更新之前和更新之后的数据设为零。尽管 total_rate 有价值。
这失败的原因是因为这里object是 a QuerySetof News_Channels,是的,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()Run Code Online (Sandbox Code Playgroud)
或者假设您不需要任何验证,您可以通过以下方式提高性能:
News_Channel.objects.filter(id=i).update(total_star=total_rate)Run Code Online (Sandbox Code Playgroud)
News_Channels如果要更新所有 News_Channels,实际上最好在Subquery此处使用 a :
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)Run Code Online (Sandbox Code Playgroud)
原因是object在您的情况下是一个查询集,并且在您尝试更新之后object[0],您不会将结果存储在数据库中,也不会刷新查询集。要使其工作,您应该将要更新的字段传递到 update 方法中。
所以,试试这个:
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)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7135 次 |
| 最近记录: |