misc: add |get_auto_geoloc filter (#49079)

This commit is contained in:
Lauréline Guérin 2020-12-04 10:35:27 +01:00
parent acefe0c493
commit d42ef313f3
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
3 changed files with 74 additions and 17 deletions

View File

@ -925,31 +925,61 @@ def test_lazy_formdata_queryset(pub, variable_test_data):
def test_lazy_formdata_queryset_distance(pub, variable_test_data):
# Form
lazy_formdata = variable_test_data
formdef = lazy_formdata._formdef
formdef.geolocations = {'base': 'Base'}
formdef.store()
data_class = lazy_formdata._formdef.data_class()
for i in range(6):
formdata = data_class()
formdata.geolocations = {'base': {'lat': i, 'lon': i}}
formdata.just_created()
formdata.store()
for i in range(4):
formdata = data_class()
formdata.geolocations = {'base': {'lat': i + 0.5, 'lon': i + 0.5}}
formdata.just_created()
formdata.jump_status('finished')
formdata.store()
# Card
CardDef.wipe()
carddef = CardDef()
carddef.name = 'items'
carddef.fields = []
carddef.geolocations = {'base': 'Base'}
carddef.store()
carddata_class = carddef.data_class()
carddata_class.wipe()
# create initial carddata like lazy_formdata, with same geolocations
carddata = carddata_class()
carddata.geolocations = {'base': {'lat': 1, 'lon': 2}}
carddata.just_created()
carddata.store()
lazy_carddata = LazyFormData(carddata)
# create objects
for i in range(6):
for dclass in [data_class, carddata_class]:
data = dclass()
data.geolocations = {'base': {'lat': i, 'lon': i}}
data.just_created()
data.store()
for i in range(4):
for dclass in [data_class, carddata_class]:
data = dclass()
data.geolocations = {'base': {'lat': i + 0.5, 'lon': i + 0.5}}
data.just_created()
data.jump_status('finished')
data.store()
# drafts
formdata = data_class()
formdata.status = 'draft'
formdata.geolocations = {'base': {'lat': 1, 'lon': 2}}
formdata.store()
carddata = carddata_class()
carddata.status = 'draft'
carddata.geolocations = {'base': {'lat': 1, 'lon': 2}}
carddata.store()
# compute distance against map field of lazy formdata
nearby = lazy_formdata.objects.distance_filter(200000)
assert len(nearby) == 6
assert set([x.number for x in nearby]) == set(['1-1', '1-3', '1-4', '1-8', '1-9', '1-10'])
nearby = lazy_carddata.objects.set_geo_center(lazy_formdata).distance_filter(200000)
assert len(nearby) == 6
assert set([x.number for x in nearby]) == set(['1-1', '1-3', '1-4', '1-8', '1-9', '1-10'])
# compute distance against geolocation
lazy_formdata._formdata.geolocations = {'base': {'lat': 2, 'lon': 2.5}}
@ -957,16 +987,29 @@ def test_lazy_formdata_queryset_distance(pub, variable_test_data):
assert len(nearby) == 6
assert set([x.number for x in nearby]) == set(['1-1', '1-4', '1-5', '1-9', '1-10', '1-11'])
assert bool(nearby) is True
nearby = lazy_carddata.objects.set_geo_center(lazy_formdata).distance_filter(200000)
assert len(nearby) == 6
assert set([x.number for x in nearby]) == set(['1-1', '1-4', '1-5', '1-9', '1-10', '1-11'])
assert bool(nearby) is True
context = pub.substitutions.get_context_variables(mode='lazy')
tmpl = Template('{{form_objects|distance_filter:200000|count}}')
assert tmpl.render(context) == '6'
tmpl = Template('{{cards|objects:"items"|set_geo_center:form|distance_filter:200000|count}}')
assert tmpl.render(context) == '6'
lazy_formdata._formdata.geolocations = {'base': {'lat': 7, 'lon': 7.5}}
nearby = lazy_formdata.objects.distance_filter(200000)
assert bool(nearby) is False
assert len(nearby) == 0
nearby = lazy_carddata.objects.set_geo_center(lazy_formdata).distance_filter(200000)
assert bool(nearby) is False
assert len(nearby) == 0
tmpl = Template('{{form_objects|distance_filter:200000|count}}')
assert tmpl.render(context) == '0'
tmpl = Template('{{cards|objects:"items"|set_geo_center:form|distance_filter:200000|count}}')
assert tmpl.render(context) == '0'
def test_lazy_formdata_queryset_filter(pub, variable_test_data):

View File

@ -564,6 +564,11 @@ def distance(obj1, obj2):
return distance
@register.filter
def set_geo_center(queryset, lazy_formdata):
return queryset.set_geo_center(lazy_formdata)
@register.filter
def distance_filter(queryset, distance=1000):
if hasattr(distance, 'get_value'):

View File

@ -36,9 +36,10 @@ from .formdef import FormDef
class LazyFormDefObjectsManager(object):
def __init__(self, formdef, formdata=None, criterias=None, order_by=None):
def __init__(self, formdef, formdata=None, geoloc_center_formdata=None, criterias=None, order_by=None):
self._formdef = formdef
self._formdata = formdata
self._geoloc_center_formdata = geoloc_center_formdata
if criterias is None:
criterias = [
NotEqual('status', 'draft'),
@ -58,9 +59,10 @@ class LazyFormDefObjectsManager(object):
def _clone(self, criterias, order_by=None):
return LazyFormDefObjectsManager(
self._formdef,
self._formdata,
criterias,
formdef=self._formdef,
formdata=self._formdata,
geoloc_center_formdata=self._geoloc_center_formdata,
criterias=criterias,
order_by=order_by or self._order_by)
def order_by(self, attribute):
@ -135,17 +137,24 @@ class LazyFormDefObjectsManager(object):
criterias = [Or([Equal('status', x) for x in status_filters])]
return self._clone(self._criterias + criterias)
def set_geo_center(self, lazy_formdata):
qs = self._clone(self._criterias)
qs._geoloc_center_formdata = lazy_formdata._formdata
return qs
def distance_filter(self, distance):
geod = Geod(ellps='WGS84')
center = self._formdata.get_auto_geoloc()
center = (self._geoloc_center_formdata or self._formdata).get_auto_geoloc()
center_lon, center_lat = center['lon'], center['lat']
def distance_check(obj):
geoloc = obj.get_auto_geoloc()
if not geoloc:
return False
# keep computed distance in object
obj._distance = geod.inv(center_lon, center_lat, geoloc['lon'], geoloc['lat'])[2]
obj._distance = geod.inv(center_lon, center_lat, geoloc['lon'], geoloc['lat'])[2]
return bool(obj._distance < distance)
return self._clone(self._criterias + [distance_check])
def filter_by(self, attribute):