2015-11-05 50 views
1

我想使用Tastypie构建一个API来获取经纬度对,然后在我的数据库中搜索位置为在该lat/long的给定距离内。要做到这一点,我的模型有一个方法,可以取得一对经/长对并从它自己的经纬线返回给定纬度/经度的距离。Django Tastypie:通过遍历model.objects.all()来过滤GET调用的结果

换句话说,我想通过示范田不过滤,而是沿着线做的事情:

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

首先,您应该重新思考您是否真的希望将RESTful类型的API用作Tastypie。因为拥有这种类型的界面非常通用,便于将数据公开给某些前端客户端,但要求您坚持不符合当前问题的规则。

如果我理解正确,您只想为此计算构建一个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') 

你可以用更多的验证,授权,认证等

EDITED升级这一观点将决定坚持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 & longitude = yyyy。记住过滤器传递的值总是字符串。确保calculate_distance可以处理它们。

+0

非常感谢您的回复!超级有用。我想我应该回去重新考虑我想用API来做什么......现在,这是我想要的唯一终端,所以我想我应该删除Tastypie,直到我真的需要RESTful。 –