ian*_*ian 1 python django django-queryset django-views
我试图避免数据库命中我的views.py。如果我使用 F() 和 ExpressionWrapper,我是否对数据库进行查询?我正在尝试优化我的代码,当我阅读文档时有点困惑。我还包含了 Models.py 以供参考。我正在对我正在工作的网络应用程序进行优化。
视图.py
from django.shortcuts import render
from django.db.models import F, Q, Count, Sum, ExpressionWrapper, IntegerField
from .models import Student, Subject, Enrollment
def home(request):
student = Student.objects.all()
subject = Subject.objects.all()
sem_score = Enrollment.objects.all().update(sem_score=ExpressionWrapper((F("prelim_score") + F("midterm_score") + F("final_score"))/3, output_field=IntegerField()))
enrollment = Enrollment.objects.all()
num_student = Enrollment.objects.all().count()
context = {"student":student, "subject":subject, "enrollment":enrollment, "num_student":num_student}
return render(request, 'core/home.html', context)
Run Code Online (Sandbox Code Playgroud)
模型.py
class Professor(models.Model):
name = models.CharField(max_length=50)
def __str__(self):
return self.name
class Student(models.Model):
name = models.CharField(max_length=50)
def __str__(self):
return self.name
class Course(models.Model):
name = models.CharField(max_length=50)
def __str__(self):
return self.name
class Subject(models.Model):
name = models.CharField(max_length=50)
course = models.ManyToManyField(Course)
enroll = models.ManyToManyField(Student, through='Enrollment')
def __str__(self):
return self.name
class Enrollment(models.Model):
GRADE_STATUS = (
("A","A"),
("B", "B"),
("C", "C"),
)
student = models.ForeignKey(Student, on_delete=models.CASCADE)
subject = models.ForeignKey(Subject, on_delete=models.CASCADE)
professor = models.ForeignKey(Professor, on_delete=models.CASCADE, null=True, blank=True)
date = models.DateTimeField(auto_now_add=True)
prelim_score = models.IntegerField(null=True, blank=True, default=0)
midterm_score = models.IntegerField(null=True, blank=True, default=0)
final_score = models.IntegerField(null=True, blank=True, default=0)
sem_score = models.IntegerField(null=True, blank=True, default=0)
sem_status = models.CharField(choices=GRADE_STATUS , max_length=50, null=True, blank=True, default=0)
def __str__(self):
return f"{self.student} enrolled in {self.subject}"
Run Code Online (Sandbox Code Playgroud)
我使用了 F() 和 ExpressionWrapper,我是否对数据库进行查询
sem_score = Enrollment.objects.all().update(
sem_score=ExpressionWrapper(
(F("prelim_score") + F("midterm_score") + F("final_score")) / 3,
output_field=IntegerField(),
)
)
Run Code Online (Sandbox Code Playgroud)
上述内容需要考虑的一些重要注意事项:
F()表达式(和ExpressionWrapper)用于定义由数据库执行的表达式,而不是由 Python 在内存中执行的表达式。Django 创建一个表达式作为发送到数据库的查询的一部分;它永远不会被 Django 评估,甚至不会返回给 Django。.update从 返回的查询集时.all(),它将立即评估查询集并执行更新。此时,查询(以及表达式)被发送到数据库,并且数据库在数据库服务器上计算表达式。因此,直接回答您的问题:不,单独调用F()orExpressionWrapper()不会查询数据库。一旦 django与数据库对话,它就会发送你的表达式以供数据库评估。表达式求值严格在数据库中进行,而不是在 Python 中进行。
此外,由于表达式中引用的模型字段F()都是相同类型,因此您不需要ExpressionWrapper:
sem_score = Enrollment.objects.all().update(
sem_score=(F("prelim_score") + F("midterm_score") + F("final_score")) / 3
)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8406 次 |
| 最近记录: |