我想使用Tastypie构建一个API,它接受一个纬度/经度长对,然后在我的数据库中搜索位置在该纬度/长度的给定距离内的所有条目。为此,我的模型有一个方法,它可以接受一个纬度/经度长对,并返回从它自己的纬度/经度到给定纬度/经度的距离。
换句话说,我想要不是通过模型字段过滤,而是通过以下方式进行过滤:
latitude = # somehow get from Tastypie request
longitude = # somehow get from Tastypie request
distance = 80
all_models = Example.objects.all()
within_range = []
for model in all_models:
distance_to_model = model.calculate_distance(latitude, longitude)
if distance_to_model <= 80:
within_range.append(model.name)
# somehow return within_range to Tastypie
我仔细阅读了文档,老实说有点不知所措 - 这是我构建的第一个API,看起来这个功能应该很容易找到,但我很难挣扎。
答案 0 :(得分:0)
首先,您应该重新考虑您是否真的想要像Tastypie那样的RESTful类型API。因为拥有这种类型的界面非常通用,可以轻松快速地将数据暴露给某些前端客户端,但要求您遵守不适合当前问题的规则。
如果我理解正确,您只想为此计算构建一个API端点。如果是,则不是使用RESTful类型API的情况。
我建议你构建一个简单的JSON视图:
@csrf_exempt
def calculate_distance(request):
# Pass data in various ways
latitude = request.GET.get('latitude') or request.POST.get('latitude')
longitude = request.GET.get('longitude') or request.POST.get('longitude')
# Or pass data as JSON in request body
if request.method != 'POST':
return HttpResponseNotAllowed(permitted_methods=('POST',))
try:
data = json.loads(request.body)
except (AttributeError, ValueError):
return HttpResponseBadRequest(json.dumps({'message': 'json format incorrect'}),
content_type='application/json')
if data.get('latitude', None) and data.get('longitude', None):
within_range = []
for location in Location.objects.all():
distance_to_model = location.calculate_distance(data['latitude'], data['longitude'])
if distance_to_model <= 80:
within_range.append(location.name)
return HttpResponse(json.dumps({'success': True,
'within_range': within_range}),
content_type='application/json')
else:
return HttpResponseBadRequest(json.dumps({'message': 'offer_id is missing'}),
content_type='application/json')
您可以使用更多验证,授权,身份验证等升级此视图。
编辑:
但是,如果您因某些原因决定坚持使用Tastypie,请在模型资源类中使用build_filters方法:
def build_filters(self, filters=None):
if filters is None:
filters = {}
orm_filters = super(OfferResource, self).build_filters(filters)
if 'pk__in' not in orm_filters:
orm_filters['pk__in'] = []
if 'latitude' in filters and 'longitude' in filters:
for entity in Example.objects.all():
distance_to_model = entity.calculate_distance(
filters['latitude'], filters['longitude'])
if distance_to_model <= 80:
orm_filters['pk__in'].append(entity.pk)
return orm_filters
现在可以请求你的资源了吗?latitude = xxx&amp; longitude = yyyy。记住过滤器传递的值总是字符串。确保calculate_distance可以处理它们。