Django 过滤带有 2 个参数的 For 循环

Django Filtering A For Loop with 2 Parameters

我构建了一个通知系统,允许用户注册自定义通知 (Notification),该通知会根据他们从另一个模型 (Report) 选择的参数和阈值触发。我的 models.py 看起来像这样:

class Report(models.Model):
    field1 = models.FloatField()
    field2 = models.FloatField()
    field3 = models.FloatField()
    ...

class Notification(models.Model):
    threshold_field = models.CharField()  # would store field1, field2, field3, etc from Report
    threshold_value = models.FloatField()  # the value corresponding to threshold_field that would trigger the notification

我正在尝试编写一个数据库查询,该查询将获取所有 Notification 满足给定 ReportReport 查询集触发通知的条件。但是,我无法弄清楚如何在查询中配对所有可能的 threshold_fieldthreshold_value 。最丑陋的可能解决方案是这样的:

report = Report.objects.first()  # get the report to query
all_fields = Report._meta.get_fields()  # all field choices from Report
all_querysets = []
for field in all_fields:  # loop through all fields, i.e. field1, field2, field3
    qs = Notification.objects.filter(
        threshold_field=field,
        threshold_value__gte=getattr(report, field)  # get the value stored in the field
    )
    all_querysets.append(qs)

这很丑陋,但这并不是一个糟糕的解决方案,因为我的作品中只有大约 20 个字段 Report。但是,有没有更好的方法来过滤 Notification 而不使用 for 循环?我知道如果我只需要查询 Notification 中的 1 个字段,这是可能的,但这里的绊脚石是 threshold_fieldthreshold_value 都依赖于循环。

部分归功于 ,我找到了解决方案。您可以使用预先准备好的 Q 查询在传递 2 个条件的多个字段中强制执行条件 OR 语句:

from django.db.models import Q

q_filter = Q(
        *[Q(threshold_field=field.name, threshold_value__gte=getattr(Report, field.name)) for field in
          Report._meta.get_fields()], _connector=Q.OR
    )  # complex filter to pair threshold field and threshold

return Notification.objects.filter(q_filter)