Commit e6635243 authored by hypsug0's avatar hypsug0
Browse files

wip: study detail sheet

parent d02dd2a7
import logging
from django.urls import reverse_lazy
from django.utils.translation import ugettext_lazy as _
from django.views.generic import DetailView, ListView
......@@ -10,6 +12,7 @@ from .forms import ActuForm
from .mixins import BlogCreateAuthMixin, BlogModifyAuthMixin
from .models import Actu
logger = logging.getLogger(__name__)
# Create your views here.
# class Actus(ListView):
......@@ -93,6 +96,7 @@ class ActuList(ListView):
def get_context_data(self, **kwargs):
context = super(ActuList, self).get_context_data(**kwargs)
logger.debug("ACTU LIST GET CONTEXT DATA")
context["icon"] = "fas fa-info-circle"
context["title"] = _("Dernières actualités")
context["sightingsicon"] = "fi-eye"
......
......@@ -1824,16 +1824,17 @@ const studyDataApp = (pk) => {
placeData: [],
sessionData: [],
sightingData: [],
dataSource: 'sessions',
dataSource: 'observations',
loading: true,
}
},
methods: {
getSightings() {
$http
.get(`/api/v1/study/${pk}/observations?format=json`)
.get(`/api/v1/study/${pk}/datas?format=json`)
.then((r) => {
this.sightingData = r.data.features
console.debug(r)
this.sightingData = r.data.results.features
console.log(this.sightingData)
this.loading = false
})
......
# import the logging library
import logging
from django.db.models import Prefetch
from rest_framework.generics import ListAPIView
from sights.models import Place
from sights.observation.api import GeoJSONSighting
from .serializers import StudySightingsSerializer
from ..models import Study
from .serializers import StudyDataSerializer
logger = logging.getLogger(__name__)
......@@ -20,9 +22,28 @@ class StudySightings(GeoJSONSighting):
return qs.distinct().order_by("-timestamp_update")
class StudySightingsTest(ListAPIView):
serializer_class = StudySightingsSerializer
class StudyDatas(ListAPIView):
serializer_class = StudyDataSerializer
queryset = (
Place.objects.select_related("created_by")
.select_related("updated_by")
.prefetch_related("sessions")
.prefetch_related("sessions__study")
.prefetch_related(Prefetch("sessions__observations"))
.prefetch_related(Prefetch("sessions__contact"))
.prefetch_related(Prefetch("sessions__observations__codesp"))
.prefetch_related(Prefetch("sessions__main_observer"))
# .prefetch_related(Prefetch("sessions__other_observer"))
)
def get_queryset(self, *args, **kwargs):
qs = Place.objects.filter(session__study=self.kwargs.get("pk"))
return qs.distinct().order_by("-timestamp_update")
qs = super().get_queryset()
pk = self.kwargs.get("pk")
logger.debug(f"pk is {pk}")
study = Study.objects.get(pk=pk)
logger.debug(f"study is {study}")
# user = self.request.user
# if study.project_manager != self.request.user.pk
qs = qs.filter(sessions__study=pk)
logger.debug(f"QS TEST {qs.query}")
return qs.distinct().order_by("-timestamp_update").all()
import logging
from rest_framework.serializers import ModelSerializer
from rest_framework_gis.serializers import GeoFeatureModelSerializer
from sights.models import Place, Session
from accounts.serializer import ProfileSearchSerializer
from sights.models import Place, Session, Sighting
from sights.observation.serializers import ContactSerializer
logger = logging.getLogger(__name__)
class SightingSerializer(ModelSerializer):
class Meta:
model = Sighting
depth = 1
fields = (
"id_sighting",
"codesp",
"breed_colo",
"total_count",
"period",
"is_doubtful",
"comment",
"timestamp_create",
)
class SessionSerializer(ModelSerializer):
contact = ContactSerializer()
observations = SightingSerializer(many=True)
main_observer = ProfileSearchSerializer()
class Meta:
model = Session
fields = ("id_session", "name", "date_start")
depth = 0
fields = ("id_session", "name", "contact", "date_start", "observations", "main_observer")
def get_observations(self, session):
observations = Sighting.objects.filter(session=session.pk).all()
return observations
class StudySightingsSerializer(ModelSerializer):
class StudyDataSerializer(GeoFeatureModelSerializer):
sessions = SessionSerializer(many=True)
class Meta:
model = Place
geo_field = "geom"
depth = 0
fields = ("name", "sessions")
def get_sessions(self, place):
sessions = Session.objects.filter(place=place.pk)
logger.debug(f"SESSIONSSSSS {sessions}")
return sessions
......@@ -95,10 +95,10 @@ class StudyDetail(LoginRequiredMixin, DetailView):
.select_related("created_by")
.select_related("updated_by")
.prefetch_related("sessions")
.prefetch_related(Prefetch("sessions__sighting_set"))
.prefetch_related(Prefetch("sessions__observations"))
.prefetch_related(Prefetch("sessions__place"))
.prefetch_related(Prefetch("sessions__contact"))
.prefetch_related(Prefetch("sessions__sighting_set__codesp"))
.prefetch_related(Prefetch("sessions__observations__codesp"))
.prefetch_related(Prefetch("sessions__main_observer"))
.prefetch_related(Prefetch("sessions__other_observer"))
)
......
......@@ -68,61 +68,54 @@
<div class="panel-heading">
<h4 class="panel-title">
<select class="pull-right input-sm" v-model="dataSource">
<option value="stats" default>statistiques générales</option>
<option value="stats">statistiques générales</option>
<option value="localités">Localités</option>
<option value="sessions">Sessions</option>
<option value="observations">Observations</option>
<option value="observations" default>Observations</option>
</select>
<i class="fas fa-clipboard-list fa-fw"></i>Données (Sessions: {{object.sessions.count}})
<i class="fas fa-clipboard-list fa-fw"></i>Données
</h4>
</div>
<div style="overflow-y: auto; max-height: 500px;">
<div v-if="dataSource=='sessions'" class="list-group">
{% for s in object.sessions.all %}
<div class="list-group-item">
<h4 class="list-group-item-heading">
<span class="pull-right label label-default label-lg">{{s.contact.descr}}</span>
{{s.place.name}} - {{s.date_start}}
</h4>
<p class="list-group-item-text">
<dl class="dl-horizontal">
<dt>Observateur principal</dt>
<dd>
{{s.main_observer.get_full_name}}</dd>
<dt>Observations</dt>
<dd>
<ul class="list-unstyled">
{%for o in s.sighting_set.all %}
<li class="{{o.codesp.sp_true|yesno:',text-muted'}}">
<strong>{{o.codesp.common_name_fr}}</strong>
(<i>{{o.codesp.sci_name}}</i>)
: {{o.total_count}}
{{o.is_breeding}}</li>
{% endfor %}
</ul>
</dd>
</dl>
</p>
</div>
{% endfor %}
</div>
<div v-if="dataSource=='observations'" class="list-group">
test
<div v-for="(s, i) in sightingData" class="list-group-item">
[[s.properties.specie_data.common_name_fr]] - [[s.properties.total_count]]
<div v-for="(sp, ip) in sightingData" class="list-group-item">
<h3 class="list-group-item-heading"><i class="fa fa-map-marker fa-fw"></i>[[sp.properties.name]]</h3>
<div class="list-group">
<div v-for="(se, ie) in sp.properties.sessions" class="list-group-item">
<h4 class="list-group-item-heading">
<span class="pull-right label label-default label-lg">[[se.contact.descr]]</span>
[[se.date_start]]
</h4>
<p class="list-group-item-text">
<dl class="dl-horizontal">
<dt>Observateur principal</dt>
<dd>
[[se.main_observer?.get_full_name]]</dd>
<dt>Observations</dt>
<dd>
<ul class="list-unstyled">
<li v-for='(o, io) in se.observations' :class="{'text-muted':!o.codesp.sp_true}">
<strong>[[o.codesp.common_name_fr]]</strong>
(<i>[[o.codesp.sci_name]]</i>)
: [[o.total_count]]
[[o.is_breeding]]</li>
</ul>
</dd>
</dl>
</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
const studyId = parseInt('{{object.pk}}')
<script>
const studyId = parseInt('{{object.pk}}')
$(document).ready(() => {
const vm = new Vue(studyDataApp(parseInt('{{object.pk}}')))
})
$(document).ready(() => {
const vm = new Vue(studyDataApp(parseInt('{{object.pk}}')))
})
</script>
{% endblock %}
</script>
{% endblock %}
from django.urls import path
from .study.api import StudySightings, StudySightingsTest
from .study.api import StudyDatas, StudySightings
from .study.views import StudyCreate, StudyDelete, StudyDetail, StudyList, StudyUpdate
from .transmitter.api import TransmitterSearchApi
from .transmitter.views import (
......@@ -24,7 +24,7 @@ urlpatterns = [
path(
"api/v1/study/<int:pk>/observations", StudySightings.as_view(), name="api_study_sightings"
),
path("api/v1/study/<int:pk>/datas", StudySightingsTest.as_view(), name="api_study_data"),
path("api/v1/study/<int:pk>/datas", StudyDatas.as_view(), name="api_study_data"),
# Transmitter relative URLS
path("transmitter/add", TransmitterCreate.as_view(), name="transmitter_create"),
path(
......
......@@ -828,7 +828,12 @@ class Session(models.Model):
contact = models.ForeignKey(
Contact, models.DO_NOTHING, default=10, verbose_name=_("Type de contact")
)
place = models.ForeignKey(Place, on_delete=models.CASCADE, verbose_name=_("Localité associée"))
place = models.ForeignKey(
Place,
on_delete=models.CASCADE,
related_name="sessions",
verbose_name=_("Localité associée"),
)
date_start = models.DateField(
verbose_name=_("Date de début"),
help_text=_("Format de date: <em>01/01/2017</em>."),
......@@ -966,7 +971,10 @@ class Sighting(models.Model):
id_sighting = models.AutoField(_("id unique"), primary_key=True)
uuid = models.UUIDField(default=uuid.uuid4, unique=True, editable=False)
session = models.ForeignKey(
Session, on_delete=models.CASCADE, verbose_name=_("Session associée")
Session,
on_delete=models.CASCADE,
verbose_name=_("Session associée"),
related_name="observations",
)
period = models.CharField(
max_length=50, blank=True, null=True, verbose_name=_("Période d'observation")
......
......@@ -60,7 +60,7 @@ class EditSighting(SightingListPermissionsMixin, ModelViewSet):
SightingEditPermission,
]
queryset = Sighting.objects.all()
queryset = Sighting.objects.select_related("session").prefetch_related("countdetails").all()
def get_queryset(self, *args, **kwargs):
qs = super().get_queryset()
......
......@@ -159,8 +159,8 @@ class PlaceDetail(PlaceViewAuthMixin, DetailView):
.select_related("contact")
.select_related("created_by")
.prefetch_related("other_observer")
.prefetch_related("sighting_set")
.prefetch_related("sighting_set__codesp")
.prefetch_related("observations")
.prefetch_related("observations__codesp")
)
# placeneighbour = Place.objects.filter(geom__within=(placeobject.geom, D(m=50)))
placedetail = False
......
......@@ -189,7 +189,7 @@ class PlaceTable(tables.Table):
"""
# id = tables.Column(accessor='id_place', verbose_name='id')
nbsession = tables.Column(
accessor="session_set.all.count", verbose_name="Sessions", orderable=False
accessor="sessions.all.count", verbose_name="Sessions", orderable=False
)
name = tables.LinkColumn("sights:place_detail", args=[A("id_place")], accessor="name")
maplocation = tables.TemplateColumn(MAPLOCATION, verbose_name="Carte", orderable=False)
......@@ -944,12 +944,12 @@ class SessionTable(tables.Table):
</div>
"""
NBTAX = """
{% ifequal 0 record.sighting_set.all.count %}
{% ifequal 0 record.observations.all.count %}
-
{% else %}
<button type="button" class="btn btn-primary btn-xs" data-toggle="modal"
data-target=".bs-session-sp-modal-md-{{ record.pk }}">
{{ record.sighting_set.count }}
{{ record.observations.count }}
</button>
<div class="modal fade bs-session-sp-modal-md-{{ record.pk }}" tabindex="-1" role="dialog"
aria-labelledby="comment">
......@@ -969,7 +969,7 @@ class SessionTable(tables.Table):
<th>codesp</th>
<th>effectif</th>
</tr>
{% for d in record.sighting_set.all %}
{% for d in record.observations.all %}
<tr{% if d.codesp.sp_true %} class="success"{% endif %}>
<td>{{ d.codesp.common_name_fr }}</td>
<td>{{ d.codesp.sci_name }}</td>
......@@ -1114,12 +1114,12 @@ class PlaceSessionTable(tables.Table):
</div>
"""
NBTAX = """
{% ifequal 0 record.sighting_set.all.count %}
{% ifequal 0 record.observations.all.count %}
-
{% else %}
<button type="button" class="btn btn-primary btn-xs" data-toggle="modal"
data-target=".bs-session-sp-modal-md-{{ record.pk }}">
{{ record.sighting_set.count }}
{{ record.observations.count }}
</button>
<div class="modal fade bs-session-sp-modal-md-{{ record.pk }}" tabindex="-1" role="dialog"
aria-labelledby="comment">
......@@ -1139,7 +1139,7 @@ class PlaceSessionTable(tables.Table):
<th>codesp</th>
<th>effectif</th>
</tr>
{% for d in record.sighting_set.all %}
{% for d in record.observations.all %}
<tr{% if d.codesp.sp_true %} class="success"{% endif %}>
<td>{{ d.codesp.common_name_fr }}</td>
<td>{{ d.codesp.sci_name }}</td>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment