给postgis的Django2给出了不可定义的类型:F()< INT()

时间:2018-04-24 07:07:04

标签: django postgis

我有以下视图和模型

@api_view(['GET', ])
def fetch_proposals_for(request, nick_of_finder, current_latitude, current_longitiude):
    finder = get_object_or_404(TinderUser, nickname=nick_of_finder)
    finder_location = Point(float(current_longitiude), float(current_latitude))

    candidates = TinderUser.objects.filter(
        last_location__distance_lte=(
            finder_location,
            D(km=min(finder.preferred_radius, F('preferred_radius'))))
    ).distance(finder_location).order_by('distance')

    if finder.preferred_sex == finder.sex:
        # deal with homosexual
        candidates_inside_finder_radius_and_vice_versa = candidates.filter(
            preferred_sex=finder.sex,
            sex=finder.preferred_sex,
            age__range=(finder.preferred_age_min, finder.preferred_age_max),
            preferred_age_min__lte=finder.age,
            preferred_age_max__gte=finder.age,
        ).exclude(nickname=finder.nickname)
    else:
        # deal with heterosexual:
        candidates_inside_finder_radius_and_vice_versa = candidates.filter(
            sex=finder.hetero_desires(),
            age__range=(finder.preferred_age_min, finder.preferred_age_max),
            preferred_age_min__lte=finder.age,
            preferred_age_max__gte=finder.age,
        ).exclude(sex=F('preferred_sex')).exclude(nickname=finder.nickname)

    paginator = Paginator(candidates_inside_finder_radius_and_vice_versa, 20)

    page = request.QUERY_PARAMS.get('page')

    try:
        result = paginator.page(page)
    except PageNotAnInteger:
        result = paginator.page(1)
    except EmptyPage:
        result = paginator.page(paginator.num_pages)

    serializer_context = {'request': request}
    serializer = TinderUserListSerializer(result, context=serializer_context)
    return Response(serializer.data)

models.py

 from django.contrib.gis.db import models
 from django.core.validators import MinValueValidator, MaxValueValidator

SEX_CHOICES = (
    ('F', 'Female',)
    ('M', 'Male',),
)


def hetero_desires(sex):
    return 'M' if sex == 'F' else 'F'


class TinderUser(models.Model):
    nickname = models.CharField(max_length=250, unique=True)
    age = models.IntegerField(validators=[MinValueValidator(18), MaxValueValidator(130)], db_index=True)
    sex = models.CharField(max_length=1, choices=SEX_CHOICES, db_index=True)
    preferred_sex = models.CharField(max_length=1, choices=SEX_CHOICES)
    preferred_age_min = models.IntegerField(validators=[MinValueValidator(18), MaxValueValidator(130)])
    preferred_age_max = models.IntegerField(validators=[MinValueValidator(18), MaxValueValidator(130)])
    last_location = models.PointField(max_length=40, null=True)
    preferred_radius = models.IntegerField(default=5, help_text="in kilometers")

    def __str__(self):
        return self.nickname

    def hetero_desires(self):
        return hetero_desires(self.sex)

当我尝试执行请求时,我得到了

  

无法解决的类型:F()< INT()

经过调查,我发现它与

有关

D(km=min(finder.preferred_radius, F('preferred_radius'))))

我正在使用的

导致问题。任何人都可以帮我解决这个问题吗?经过大量的搜索,我找不到任何解决方案。请帮忙

1 个答案:

答案 0 :(得分:2)

我认为你得到了错误,因为python的内置min()函数不适用于F表达式。您可以尝试做的是使用min_radius列注释查询,然后执行距离过滤。

candidates = TinderUser.objects.annotate(
    min_radius=Min(finder.preferred_radius, F('preferred_radius'))
)
candidates = candidates.filter(
    last_location__distance_lte=(
        finder_location, D(km=F('min_radius'))
    )
)