我有一個像這樣的經理模型的GeoDjango項目;Python TastyPie - 自定義管理器方法作爲過濾器?
class AdvertManager(models.GeoManager):
def within_box(self, x0, y0, x1, y1):
geometry = Polygon.from_bbox((x0, y0, x1, y1,))
return self.filter(point__within=geometry)
我試圖讓我的資源模型(AdvertResource)通過一個GET參數來暴露within_box函數,就像;
http://127.0.0.1:8000/api/v1/advert/?format=json&box=51.623349,-3.25362,51.514195,-3.4754133
我開始在資源模型上寫這樣一個build_filters
方法;
def build_filters(self, filters=None):
if not filters:
filters = {}
orm_filters = super(AdvertResource, self).build_filters(filters)
if 'box' in filters:
points = [float(p.strip()) for p in filters['box'].split(',')]
orm_filters = {'box': Advert.objects.within_box(*points).all()}
return orm_filters
但是,這會引發錯誤「無法解析關鍵字」框'入字段...「。
是否有可能將自定義管理器的方法暴露給api url?
編輯 - 我現在用下面的解決方案解決了這個問題。
class AdvertResource(ModelResource):
longitude = fields.FloatField(attribute='longitude', default=0.0)
latitude = fields.FloatField(attribute='latitude', default=0.0)
author = fields.ForeignKey(UserResource, 'author')
def build_filters(self, filters=None):
"""
Build additional filters
"""
if not filters:
filters = {}
orm_filters = super(AdvertResource, self).build_filters(filters)
if 'point__within_box' in filters:
points = filters['point__within_box']
points = [float(p.strip()) for p in points.split(',')]
orm_filters['within_box'] = points
return orm_filters
def apply_filters(self, request, applicable_filters):
"""
Apply the filters
"""
if 'within_box' in applicable_filters:
area = applicable_filters.pop('within_box')
poly = Polygon.from_bbox(area)
applicable_filters['point__within'] = poly
return super(AdvertResource, self).apply_filters(request,
applicable_filters)
現在,這意味着該請求http://127.0.0.1:8000/api/v1/advert/?format=json&point__within_box=51.623349,-3.25362,51.514195,-3.4754133
現在過濾邊框範圍內的結果。