如何实现更复杂的过滤器?

时间:2018-02-11 08:41:42

标签: django django-models django-views

我正在尝试根据特定条件查询用户子集。大多数条件下的过滤相对简单,但有些过于复杂。例如,这是一个我试图合并到查询过滤器中的函数:

def prefs_are_none(profile):
    none = True
    if profile.get_faves() or profile.get_choices():
        none = False
    return none  

我不确定如何将此功能添加到此查询中:

user_list = Profile.objects.annotate(
                        distance_away=Distance(
                            'last_location', current_user.last_location
                        )
                    ).filter(last_location__distance_lte=(
                        current_user.last_location, D(km=200)
                    ), public=True, # additional filters would ideally go here)  

这是Profile的模型,它清除了上面使用的某些方法(get_faves(),get_choices()):

class Profile(models.Model):
    fave1 = models.CharField(max_length=54, blank=True, null=True,
                              verbose_name='Learn A')
    fave2 = models.CharField(max_length=54, blank=True, null=True,
                              verbose_name='Learn B')
    choice1 = models.CharField(max_length=54, blank=True, null=True,
                              verbose_name='Teach A')
    choice2 = models.CharField(max_length=54, blank=True, null=True,
                              verbose_name='Teach B')
    public = models.BooleanField(default=False, verbose_name='Public')

    last_location = models.PointField(null=True)

    objects = ProfileManager()

    def __str__(self):
        return self.user.username

    def get_faves(self):
        list_of_faves = [self.fave1, self.fave2]
        return [field for field in list_of_faves if field]

    def get_choices(self):
        list_of_choices = [self.choice1, self.choice2]
        return [field for field in list_of_choices if field]  

所以基本上在查询中我试图通过get_faves()get_choices()函数检查一个配置文件没有空 - 这就是{{1}中正在发生的事情功能。
我如何将所有这些功能合并到查询中?

1 个答案:

答案 0 :(得分:2)

您需要在queryset中实现or条件。您可以使用Q objects执行此操作:

from django.db.models import Q
Profile.objects.filter(
      Q(fave1__isnull=False) | Q(fave2__isnull=False),
      Q(choice1__isnull=False) | Q(choice1__isnull=False),
      last_location__distance_lte=(current_user.last_location, D(km=200)),
      public=True
)

在此示例中,使用Q加入的|个对象会向查询添加or个条件。