我有以下视图和模型
@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'))))
导致问题。任何人都可以帮我解决这个问题吗?经过大量的搜索,我找不到任何解决方案。请帮忙
答案 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'))
)
)