Список фильтров администратора Django с дополнительными методами настраиваемого менеджера моделей - PullRequest
2 голосов
/ 03 февраля 2012

У меня есть модель Address, которая содержит два поля с плавающей запятой, lat и lng.Я написал собственный менеджер моделей с методом nearby(lat, lng, distance), который использует сырой SQL для возврата только Address, которые находятся в пределах определенного радиуса.(GeoDjango оказался излишним).

Пример вызова: Address.objects.nearby(53.3, 13.4, 10) (возвращает QuerySet)

Теперь я хочу динамически фильтровать Address объекты в администраторе Django, используя этот метод (в идеале позволяяпользователь выбирает местоположение на карте Google и максимальное расстояние с помощью ползунка).Я понятия не имею, как этого достичь.Кто-нибудь может указать мне правильное направление?

УТОЧНЕНИЕ Вам не нужно писать какой-либо JavaScript для меня, я просто хочу знать, как заставить администратора Django оценивать дополнительные параметры запроса вURL, так что я могу делать запросы, такие как /admin/appname/address/?lat=53&long=13&dist=10.Затем я, вероятно, смогу выяснить, как вставить карту Google и требуемую магию JavaScript в шаблон самостоятельно.

ОБНОВЛЕНИЕ Я пытался перезаписать queryset в ModelAdmin следующим образом:

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 ]

0 голосов
/ 03 февраля 2012

Я добавил это в ModelAdmin класса объекта, который имеет address как FK:

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.

Есть ли лучшее решение?

0 голосов
/ 03 февраля 2012

Если вам нужна эта функция на странице отображения списка администратора, вы можете написать собственный фильтр.

См. Решение в: Пользовательский фильтр в Django Admin на Django 1.3 или ниже .

...