Commit 965778ad authored by hypsug0's avatar hypsug0
Browse files

Merge branch 'study_territory_in_search' into develop

parents fda24ad8 f5643d7d
# -*- coding: utf-8 -*-
from django.contrib.auth.decorators import login_required
# from django.contrib.auth.decorators import login_required
from django.urls import path
from djgeojson.views import GeoJSONLayerView
from sights.models import Municipality, Territory
from .views import (
from .views import ( # GeoJSONTiledPlaceData,
ActiveUserAutocomplete,
AllUserAutocomplete,
GeoJSONTiledPlaceData,
MetaPlaceAutocomplete,
MunicipalityAutocomplete,
PlaceAutocomplete,
StudyAutocomplete,
TaxaAutocomplete,
TerritoryAutocomplete,
metaplaces_as_geojson,
places_as_geojson,
places_in_metaplace_as_geojson,
places_in_metaplaces_as_geojson,
)
# from sights.models import Municipality, Territory
# from djgeojson.views import GeoJSONLayerView
app_name = "general_api"
urlpatterns = [
path(
"municipality.geojson",
login_required(
GeoJSONLayerView.as_view(
model=Municipality,
precision=3,
simplify=0.5,
properties=("name", "code"),
)
),
name="geodata_municipality",
),
path(
"territory.geojson",
login_required(
GeoJSONLayerView.as_view(
model=Territory, precision=3, simplify=0.5, properties=("name", "code")
)
),
name="geodata_territory",
),
# path(
# "municipality.geojson",
# login_required(
# GeoJSONLayerView.as_view(
# model=Municipality,
# precision=3,
# simplify=0.5,
# properties=("name", "code"),
# )
# ),
# name="geodata_municipality",
# ),
# path(
# "territory.geojson",
# login_required(
# GeoJSONLayerView.as_view(
# model=Territory, precision=3, simplify=0.5, properties=("name", "code")
# )
# ),
# name="geodata_territory",
# ),
path("place.geojson", places_as_geojson, name="geodata_place"),
path("metaplaces.geojson", metaplaces_as_geojson, name="geodata_metaplaces"),
path(
"metaplaces/places.geojson",
places_in_metaplaces_as_geojson,
places_in_metaplace_as_geojson,
name="geodata_places_in_metaplaces",
),
path(
......@@ -57,11 +59,11 @@ urlpatterns = [
places_in_metaplace_as_geojson,
name="geodata_place_in_metaplace",
),
path(
"place/<int:z>/<int:x>/<int:y>",
GeoJSONTiledPlaceData.as_view(),
name="placetiled",
),
# path(
# "place/<int:z>/<int:x>/<int:y>",
# GeoJSONTiledPlaceData.as_view(),
# name="placetiled",
# ),
path(
"active-user-autocomplete/",
ActiveUserAutocomplete.as_view(),
......@@ -89,4 +91,9 @@ urlpatterns = [
MetaPlaceAutocomplete.as_view(),
name="metaplace_autocomplete",
),
path(
"v1/study/search",
StudyAutocomplete.as_view(),
name="study_autocomplete",
),
]
......@@ -8,13 +8,16 @@ from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.serializers import serialize
from django.db.models import Q
from django.http import HttpResponse
from djgeojson.views import GeoJSONLayerView, TiledGeoJSONLayerView
from accounts.models import UserFullName
from dicts.models import Specie
from geodata.models import Municipality, Territory
from management.models import Study
from sights.models import MetaPlace, Place
# from djgeojson.views import GeoJSONLayerView, TiledGeoJSONLayerView
# Get an instance of a logger
logger = logging.getLogger(__name__)
......@@ -153,8 +156,8 @@ class PlaceAutocomplete(LoginRequiredMixin, autocomplete.Select2QuerySetView):
return qs
class GeoJSONData(LoginRequiredMixin, GeoJSONLayerView):
pass
# class GeoJSONData(LoginRequiredMixin, GeoJSONLayerView):
# pass
# class GeoJSONPlaceData(LoginRequiredMixin, GeoJSONLayerView):
......@@ -184,50 +187,50 @@ class GeoJSONData(LoginRequiredMixin, GeoJSONLayerView):
# return new_context
class TiledGeoJSONData(LoginRequiredMixin, TiledGeoJSONLayerView):
pass
# class TiledGeoJSONData(LoginRequiredMixin, TiledGeoJSONLayerView):
# pass
class GeoJSONTiledPlaceData(LoginRequiredMixin, TiledGeoJSONLayerView):
model = Place
properties = ("pk", "name", "sessions")
# queryset = Place.objects.filter(telemetric_crossaz=False).annotate(sessions=Count('session')).all()
# class GeoJSONTiledPlaceData(LoginRequiredMixin, TiledGeoJSONLayerView):
# model = Place
# properties = ("pk", "name", "sessions")
# # queryset = Place.objects.filter(telemetric_crossaz=False).annotate(sessions=Count('session')).all()
def get_queryset(self):
loggeduser = self.request.user
user = get_user_model().objects.get(id=loggeduser.id)
qs = super(GeoJSONTiledPlaceData, self).get_queryset()
qs = qs.filter(telemetric_crossaz=False)
if user.access_all_data is True:
logger.debug("Chargement de la carte pour l'utilisateur avec accès total")
qs = qs
elif user.is_resp:
logger.debug("Chargement de la carte pour le Coordinateur")
logger.debug(user.id)
logger.debug(loggeduser.id)
respterritory = user.resp_territory.all()
qs = qs.filter(
Q(territory__in=respterritory)
| (
(
~Q(territory__in=respterritory)
& (
Q(is_hidden=False)
| (
Q(is_hidden=True)
& (Q(created_by=loggeduser) | Q(authorized_user=loggeduser))
)
)
)
)
)
else:
logger.debug("Chargement de la carte pour l'obs lambda")
qs = qs.filter(
Q(is_hidden=False)
| (Q(is_hidden=True) & Q(authorized_user__username__contains=loggeduser.username))
)
return qs
# def get_queryset(self):
# loggeduser = self.request.user
# user = get_user_model().objects.get(id=loggeduser.id)
# qs = super(GeoJSONTiledPlaceData, self).get_queryset()
# qs = qs.filter(telemetric_crossaz=False)
# if user.access_all_data is True:
# logger.debug("Chargement de la carte pour l'utilisateur avec accès total")
# qs = qs
# elif user.is_resp:
# logger.debug("Chargement de la carte pour le Coordinateur")
# logger.debug(user.id)
# logger.debug(loggeduser.id)
# respterritory = user.resp_territory.all()
# qs = qs.filter(
# Q(territory__in=respterritory)
# | (
# (
# ~Q(territory__in=respterritory)
# & (
# Q(is_hidden=False)
# | (
# Q(is_hidden=True)
# & (Q(created_by=loggeduser) | Q(authorized_user=loggeduser))
# )
# )
# )
# )
# )
# else:
# logger.debug("Chargement de la carte pour l'obs lambda")
# qs = qs.filter(
# Q(is_hidden=False)
# | (Q(is_hidden=True) & Q(authorized_user__username__contains=loggeduser.username))
# )
# return qs
@login_required
......@@ -368,3 +371,17 @@ def places_in_metaplace_as_geojson(request, pk):
field = ("pk", "name")
geojson = serialize("geojson", place_list, geometry_field="geom", fields=field)
return HttpResponse(geojson, content_type="application/json")
class StudyAutocomplete(autocomplete.Select2QuerySetView):
def get_queryset(self):
# Don't forget to filter out results depending on the visitor !
if not self.request.user.is_authenticated:
return Study.objects.none()
qs = Study.objects.all().order_by("name")
if self.q:
qs = qs.filter(name__icontains=self.q)
return qs
......@@ -587,7 +587,7 @@ const placeSearchBlock = () => {
}
const showValues = () => {
const str = $('#searchForm input')
const str = $('#searchForm input, select')
.map(function () {
return $(this).val().trim() == '' ? null : this
})
......@@ -955,7 +955,7 @@ const sightingSearchBlock = () => {
})
function showValues() {
var str = $('#searchForm input')
var str = $('#searchForm input, select')
.map(function () {
return $(this).val().trim() == '' ? null : this
})
......
......@@ -32,3 +32,4 @@ sqlparse==0.3.0
tablib==0.13.0
xlrd==1.2.0
xlwt==1.3.0
django-registration-redux==2.8
......@@ -443,7 +443,7 @@ class CountDetailEditAuthMixin:
class LargeGeoJsonPageNumberPagination(GeoJsonPagination):
page_size = 100
page_size_query_param = "page_size"
max_page_size = 1000
max_page_size = 5000
class PlaceFilteringMixin:
......@@ -462,6 +462,7 @@ class PlaceFilteringMixin:
metaplace = self.request.query_params.get("metaplace", None)
convention = self.request.query_params.get("convention", None)
managed = self.request.query_params.get("managed", None)
territory = self.request.query_params.get("territory", None)
qs = Place.objects.order_by("-timestamp_create")
......@@ -510,6 +511,7 @@ class PlaceFilteringMixin:
if creator is not None
else qs
)
qs = qs.filter(territory__id=territory) if territory is not None else qs
qs = qs.select_related("created_by", "type").prefetch_related(
Prefetch("municipality", queryset=Municipality.objects.only("name", "code"))
......@@ -579,6 +581,7 @@ class SightingFilteringMixin:
sexual_status = self.request.query_params.get("sexual_state", None)
age = self.request.query_params.get("age", None)
breed_colo = self.request.query_params.get("breed_colo", None)
territory = self.request.query_params.get("territory", None)
qs = (
qs.filter(
......@@ -673,6 +676,9 @@ class SightingFilteringMixin:
)
qs = qs.filter(period__icontains=period) if period is not None else qs
qs = qs.filter(breed_colo=True) if breed_colo is not None else qs
qs = qs.filter(period__icontains=period) if period is not None else qs
qs = qs.filter(breed_colo=True) if breed_colo is not None else qs
qs = qs.filter(session__place__territory__id=territory) if territory is not None else qs
return qs
......
......@@ -32,6 +32,8 @@ from sights.tables import (
SightingTable,
)
from geodata.models import Territory
IMAGE_FILE_TYPES = ["png", "jpg", "jpeg"]
DOCUMENT_FILE_TYPES = ["doc", "docx", "odt", "pdf"]
......@@ -290,6 +292,9 @@ class SightingSearch(LoginRequiredMixin, TemplateView):
def get_context_data(self, **kwargs):
context = super(SightingSearch, self).get_context_data(**kwargs)
enable_territory = Territory.objects.filter(coverage=True).all()
print(enable_territory)
context['enable_territory']=enable_territory
context["icon"] = "fa fa-fw fa-eye"
context["title"] = _("Rechercher une observation")
context[
......
......@@ -20,6 +20,7 @@ from django.views.generic.edit import CreateView, DeleteView, UpdateView
from core import js
from dbchiro.settings.base import SEE_ALL_NON_SENSITIVE_DATA
from geodata.models import Territory
from ..forms import (
BridgeForm,
......@@ -314,30 +315,14 @@ class PlaceDelete(PlaceEditAuthMixin, DeleteView):
return context
#
# class PlaceList(
# LoginRequiredMixin, FilterView, ExportMixin, SingleTableView, TemplateView
# ):
# class PlaceList(LoginRequiredMixin, TemplateView):
# template_name = "sights/place_search.html"
# def get_context_data(self, **kwargs):
# context = super(PlaceList, self).get_context_data(**kwargs)
# context["icon"] = "fa fa-fw fa-map"
# context["title"] = _("Rechercher une localité")
# context["createplacebtn"] = True
# context[
# "js"
# ] = """
# """
# return context
class PlaceList(LoginRequiredMixin, TemplateView):
template_name = "sights/place_search.html"
def get_context_data(self, **kwargs):
context = super(PlaceList, self).get_context_data(**kwargs)
enable_territory = Territory.objects.filter(coverage=True).all()
print(enable_territory)
context["enable_territory"] = enable_territory
context["icon"] = "fa fa-fw fa-map"
context["title"] = _("Rechercher une localité")
context["createplacebtn"] = True
......
{% extends 'base_fullwidth_leaflet.html' %}
{% load leaflet_tags i18n staticfiles crispy_forms_tags django_tables2 geojson_tags %}
{% leaflet_js %} {% leaflet_css %}
{% block jsvar %} {% endblock %}
{% extends 'base_fullwidth_leaflet.html' %}
{% load leaflet_tags i18n staticfiles crispy_forms_tags django_tables2 geojson_tags %}
{% leaflet_js %} {% leaflet_css %}
{% block jsvar %} {% endblock %}
{% block content %}
<style>
.leaflet-container-default {
......@@ -40,6 +40,15 @@
<div class="panel-body">
<form id="searchForm" class="form-inline text-center">
<div class="form-row">
<div class="form-group form-group-sm mr-2">
<label for="territory" class="control-label">Département</label>
<select class="form-control form-control-sm" name="territory" id="territory">
<option value="">-</option>
{% for t in enable_territory %}
<option value="{{t.id}}">{{ t.name }} ({{ t.code }})</option>
{% endfor %}
</select>
</div>
<div class="form-group form-group-sm mr-2">
<label for="municipality" class="control-label"
>Commune</label
......@@ -141,8 +150,14 @@
placeholder="Altitude maxi"
/>
</div>
<div class="form-group form-group-sm mr-2">
<label for="page_size">Nombre de donnnées à afficher</label>
<input class="form-control form-control-sm" type="number" id="page_size"
name="page_size" min="1000" max="5000" step="1000"
placeholder="Nombre de données">
</div>
</div>
<span id="results"></span>
<span id="results"></span>
</form>
</div>
</div>
......
......@@ -14,116 +14,131 @@
height: 800px;
min-height: 800px;
}
</style>
<h1>{% if createplacebtn %}<a href="{% url 'sights:place_create' %}" class="btn btn-primary pull-right"><i
class="fa fa-fw fa-map-marker-alt"></i>{% trans 'Créer une observation' %}</a>{% endif %}<i
class="fa fa-fw fa-map-marker-alt"></i>{% trans 'Créer une observation' %}</a>{% endif %}<i
class="{{ icon | safe }}"></i> {{ title | safe }}</h1>
{% comment %}Tableau de recherche avec filtrage {% endcomment %}
<div class="col-sm-12 col-md-6 col-lg-7">
<div class="panel panel-default">
<div class="panel-body">
{# <form action="" method="get">#}
{# {% crispy filter.form %}#}
{# </form>#}
<form id="searchForm" class="form-inline text-center">
<div class="form-row">
<div class="form-group form-group-sm mr-2">
<label for="territory" class="control-label">Département</label>
<select class="form-control form-control-sm" name="territory" id="territory">
<option value="">-</option>
{% for t in enable_territory %}
<option value="{{t.id}}">{{ t.name }} ({{ t.code }})</option>
{% endfor %}
</select>
</div>
<div class="form-group form-group-sm mr-2">
<label for="municipality">Commune</label>
<input class="form-control form-control-sm" type="text" id="municipality" name="municipality"
placeholder="Commune">
<input class="form-control form-control-sm" type="text" id="municipality"
name="municipality" placeholder="Commune">
</div>
<div class="form-group form-group-sm mr-2">
<label for="type">Nom</label>
<input class="form-control form-control-sm" type="text" id="name" name="name" placeholder="Nom">
<input class="form-control form-control-sm" type="text" id="name" name="name"
placeholder="Nom">
</div>
<div class="form-group form-group-sm mr-2">
<label for="type">Métasite</label>
<label for="metaplace">Métasite</label>
<input class="form-control form-control-sm" type="text" id="metaplace" name="metaplace"
placeholder="Métasite">
placeholder="Métasite">
</div>
<!-- <div class="form-group form-group-sm mr-2 ui-widget">-->
<!-- <label for="study">Etude</label>-->
<!-- <input class="form-control form-control-sm" type="text" id="study" name="study"-->
<!-- placeholder="Etude">-->
<!-- </div>-->
</div>
<div class="form-row">
<div class="form-group form-group-sm mr-2">
<input id="gite" name="gite" type="checkbox" class="form-check-input" id="gite">
<input id="gite" name="gite" type="checkbox" class="form-check-input">
<label class="form-check-label" for="gite">Gite</label>
</div>
<div class="form-group form-group-sm mr-2">
<input id="breed_colo" name="breed_colo" type="checkbox" class="form-check-input" id="gite">
<input id="breed_colo" name="breed_colo" type="checkbox" class="form-check-input">
<label class="form-check-label" for="breed_colo">Colonie de reproduction</label>
</div>
<div class="form-group form-group-sm mr-2">
<label for="place_type">Type de localité</label>
<input class="form-control form-control-sm" type="text" id="place_type" name="place_type"
placeholder="Type de localité">
</div>
</div>
<div class="form-row">
<div class="form-group form-group-sm mr-2">
<label for="specie">Espèce</label>
<input class="form-control form-control-sm" type="text" id="specie" name="specie"
placeholder="Espèce">
placeholder="Type de localité">
</div>
<div class="form-group form-group-sm mr-2">
<label for="count_min">Effectif mini</label>
<input class="form-control form-control-sm" type="number" id="count_min" name="count_min"
placeholder="Effectif mini">
</div>
<div class="form-group form-group-sm mr-2">
<label for="count_max">Effectif maxi</label>
<input class="form-control form-control-sm" type="number" id="count_max" name="count_max"
placeholder="Effectif maxi">
</div>
</div>
<div class="form-row">
<div class="form-group form-group-sm mr-2">
<label for="sex">Sexe</label>
<input class="form-control form-control-sm" type="text" id="sex" name="sex" placeholder="Sexe">
<input class="form-control form-control-sm" type="text" id="sex" name="sex"
placeholder="Sexe">
</div>
<div class="form-group form-group-sm mr-2">
<label for="sexual_status">Etat sexuel</label>
<input class="form-control form-control-sm" type="text" id="sexual_status" name="sexual_status"
placeholder="Etat sexuel">
<input class="form-control form-control-sm" type="text" id="sexual_status"
name="sexual_status"
placeholder="Etat sexuel">
</div>
<div class="form-group form-group-sm mr-2">
<label for="age">Age</label>
<input class="form-control form-control-sm" type="text" id="age" name="age" placeholder="Age">
<input class="form-control form-control-sm" type="text" id="age" name="age"
placeholder="Age">
</div>
</div>
<div class="form-row">
<div class="form-group form-group-sm mr-2">
<label for="date_min">Date mini</label>
<input class="form-control form-control-sm" type="date" id="date_min" name="date_min"
placeholder="Date minimale">
<input class="form-control form-control-sm" type="date" id="date_min"
name="date_min"
placeholder="Date minimale">
</div>
<div class="form-group form-group-sm mr-2">
<label for="date_max">Date maxi</label>
<input class="form-control form-control-sm" type="date" id="date_max" name="date_max"
placeholder="Date maximale">
<input class="form-control form-control-sm" type="date" id="date_max"
name="date_max"
placeholder="Date maximale">
</div>
<div class="form-group form-group-sm mr-2">
<label for="period">Période</label>
<input class="form-control form-control-sm" type="select" id="period" name="period"
placeholder="Période">
<input class="form-control form-control-sm" type="select" id="period"
name="period"
placeholder="Période">
</div>
</div>
<div class="form-row">
<div class="form-group form-group-sm mr-2">
<label for="contact_type">Type de contact</label>
<input class="form-control form-control-sm" type="text" id="contact_type" name="contact_type"
placeholder="Type de contact">
<input class="form-control form-control-sm" type="text" id="contact_type"
name="contact_type"
placeholder="Type de contact">
</div>
<div class="form-group form-group-sm mr-2">
<label for="alt_min">Altitude mini</label>
<input class="form-control form-control-sm" type="number" id="alt_min" name="alt_min"
placeholder="Altitude mini">
<input class="form-control form-control-sm" type="number" id="alt_min"
name="alt_min"
placeholder="Altitude mini">
</div>
<div class="form-group form-group-sm mr-2">
<label for="alt_max">Altitude maxi</label>
<input class="form-control form-control-sm" type="number" id="alt_max" name="alt_max"
placeholder="Altitude maxi">
<input class="form-control form-control-sm" type="number" id="alt_max"
name="alt_max"
placeholder="Altitude maxi">
</div>
<div class="form-group form-group-sm mr-2">
<label for="page_size">Nombre de donnnées à afficher</label>
<input class="form-control form-control-sm" type="number" id="page_size"
name="page_size" min="1000" max="5000" step="1000"
placeholder="Nombre de données">
</div>
</div>
</form>
......@@ -136,7 +151,8 @@
{% if export %}
<div class="btn-group btn-group-xs pull-right">
<button type="button" class="btn btn-primary btn-xs dropdown-toggle" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false">
aria-haspopup="true"
aria-expanded="false">
{% trans 'Exporter' %} <span class="caret"></span>
</button>
<ul class="dropdown-menu">
......@@ -153,25 +169,26 @@
{% endif %}
<div class="panel panel-default table-responsive">
{# {% render_table table %}#}
{# {% render_table table %}#}
<table id="sight_results" class="table table-striped table-condensed" cellspacing="0" width="100%">
<thead>
<tr>
<th>+</th>
<th>Actions</th>
<th>Espèce</th>
<th>Effectif</th>
<th>Colonie de reproduction</th>
<th>Localité</th>
<th>Commune</th>
<th>Date</th>
<th>Session</th>