Использование prefetch_related для сокращения дорогостоящих запросов
Как я могу сделать запрос на уровне базы данных. в моем коде для назначения писем в список я использую код python вместо этого я хочу использовать ORM запрос т.е. на уровне базы данных как мой запрос может выглядеть здесь.
models.py
class UserModel(models.Model):
email = models.EmailField(unique=True, blank=True, null=True)
class Mymodel(models.Model):
name = models.CharField(max_length=300)
assignees = models.ManyToManyField(
User,
related_name='tasks',
blank=True,
)
send_email = models.BooleanField(default=False)
views.py
def my_view(self):
due_date = datetime.date.today()
records = Mymodel.objects.filter(due_date=due_date)
for rec in records:
if rec.send_email:
responsible_emails = []
for person in rec.assignees.all():
responsible_emails.append(person.email)
Вы, конечно, можете использовать prefetch_related()
, чтобы сделать запрос более эффективным, но причина того, что ваш код работает медленно, заключается в том, что у вас есть вызовы БД, вложенные в цикл for. Вы можете переписать свои запросы так, чтобы они по сути выполняли логику if-выражения и for-петли:
def my_view(self):
...
# move your if-statement to the model filter
records = Mymodel.objects.filter(
due_date=due_date,
send_email=True
).prefetch_related('assignees')
# loop through each record (is this necessary?)
for record in records:
# get a list of email addresses
responsible_emails = rec.assignees.values_list('email', flat=True)
Вы можете сделать запрос из самого UserModel
следующим образом.
due_date = datetime.date.today()
UserModel.objects.prefetch_related("tasks").filter(
tasks__send_email=True, tasks__due_date=due_date
).values_list("email", flat=True)