Django 管理后台自定义模型管理器过滤列表附加方法

3 投票
2 回答
1637 浏览
提问于 2025-04-17 12:13

我有一个叫做Address的模型,它里面有两个浮点数字段,分别是lat(纬度)和lng(经度)。我写了一个自定义的模型管理器,里面有一个nearby(lat, lng, distance)的方法,这个方法使用原始SQL查询,只返回在某个半径范围内的Address对象。(我觉得用GeoDjango太复杂了)。

举个例子,调用方式是: Address.objects.nearby(53.3, 13.4, 10)(这会返回一个查询集)。

现在我想在Django的管理后台动态过滤Address对象,理想情况下是让用户在谷歌地图上选择一个位置,并通过滑块选择最大距离。我不知道该怎么做。有没有人能给我指个方向?

澄清一下 我不需要你给我写任何JavaScript,我只是想知道怎么让Django管理后台在URL中评估额外的查询参数,这样我就可以进行像/admin/appname/address/?lat=53&long=13&dist=10这样的查询。我可能能自己搞定把谷歌地图和所需的JavaScript代码放到模板里。

更新 我尝试在ModelAdmin中重写queryset,像这样:

def queryset(self, request):
    try:
        lat = float(request.REQUEST['lat'])
        lng = float(request.REQUEST['lng'])
        dist  = int(request.REQUEST['dist'])
        matches = Address.objects.nearby(lat=lat, lng=lng, dist=dist)
        return matches
    except:
        return super(ReportAdmin, self).queryset(request)

但是,管理后台不喜欢这样,返回了?e=1,并没有过滤结果。

2 个回答

-1

如果你想在管理员列表显示页面上实现这个功能,你可以写一个自定义的过滤器。

你可以查看这个解决方案:Django 1.3 或更早版本的 Django 管理员中的自定义过滤器

0

我把这个添加到了有address作为外键的对象类的ModelAdmin里:

def lookup_allowed(self, lookup, *args, **kwargs):
    if lookup == 'address__dst':
        return True
    return super(ReportAdmin, self).lookup_allowed(lookup, args, **kwargs)

我把这个添加到了模型里

def _filter_or_exclude(self, negate, *args, **kwargs):
    try:
        value = kwargs.pop('address__dst')
        matches = self.nearby(*map(float, value.split(',')))
        pks = [m.pk for m in matches]
        kwargs.update({ 'pk__in': pks })
    except:
        pass
    return super(ReportQuerySet, self)._filter_or_exclude(negate, *args, **kwargs)

这样我就可以像这样进行过滤:?address_dst=lat,lng,dst

有没有更好的解决办法呢?

撰写回答