Использование 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)

Вернуться на верх