Django Tastypie:通过循环遍历model.objects.all()来过滤GET调用的结果

时间:2015-11-05 05:19:05

标签: python django tastypie

我想使用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,看起来这个功能应该很容易找到,但我很难挣扎。

1 个答案:

答案 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可以处理它们。