changes display of notes in tables (headers on the side)

corrects code for 'notes' modules according to PEP8 guidelines
This commit is contained in:
artus40
2017-12-27 12:42:40 +01:00
parent 8092859cb4
commit f8e618e08a
10 changed files with 171 additions and 132 deletions

View File

@@ -1,5 +1,4 @@
from .models import Sujet from statistiques.models import NSP
from statistiques.models import FicheStatistique, NSP
def merge_stats(main, merged): def merge_stats(main, merged):
@@ -21,17 +20,18 @@ def merge_stats(main, merged):
for field in ('prob_psychiatrie', 'prob_somatique', for field in ('prob_psychiatrie', 'prob_somatique',
'prob_administratif', 'prob_addiction', 'prob_administratif', 'prob_addiction',
'connu_siao', 'lien_familial'): 'connu_siao', 'lien_familial'):
if not getattr(main.statistiques, field): # Ignore if already filled if not getattr(main.statistiques, field): # Ignore if already filled
setattr(main.statistiques, field, getattr(merged.statistiques, field, None)) setattr(main.statistiques, field, getattr(merged.statistiques, field, None))
# Choice fields, None is NSP # Choice fields, None is NSP
for field in ('habitation', 'ressources', 'parcours_de_vie'): for field in ('habitation', 'ressources', 'parcours_de_vie'):
if getattr(main.statistiques, field) == NSP: # Ignore if already filled if getattr(main.statistiques, field) == NSP: # Ignore if already filled
setattr(main.statistiques, field, getattr(merged.statistiques, field, NSP)) setattr(main.statistiques, field, getattr(merged.statistiques, field, NSP))
def merge_two(main, merged): def merge_two(main, merged):
""" Merge 'merged' sujet into 'main' one """ """ Merge 'merged' sujet into 'main' one """
merge_stats(main, merged) # Merge statistics and informations merge_stats(main, merged) # Merge statistics and informations
for note in merged.notes.all(): # Move all notes for note in merged.notes.all(): # Move all notes
note.sujet = main note.sujet = main
note.save() note.save()
main.save() main.save()

View File

@@ -1,9 +1,10 @@
from django.apps import AppConfig from django.apps import AppConfig
from watson import search as watson from watson import search as watson
class NotesConfig(AppConfig): class NotesConfig(AppConfig):
name = 'notes' name = 'notes'
def ready(self): def ready(self):
Sujet = self.get_model("Sujet") sujet_model = self.get_model("Sujet")
watson.register(Sujet, fields=('nom', 'prenom', 'surnom')) watson.register(sujet_model, fields=('nom', 'prenom', 'surnom'))

View File

@@ -6,8 +6,8 @@ from utilisateurs.models import Professionnel
from django import forms from django import forms
from django_select2.forms import Select2Widget from django_select2.forms import Select2Widget
### NOTES
# NOTES
class NoteForm(forms.ModelForm): class NoteForm(forms.ModelForm):
""" Generic Note form """ """ Generic Note form """
class Meta: class Meta:
@@ -15,11 +15,12 @@ class NoteForm(forms.ModelForm):
fields = ['sujet', 'text', 'created_by', 'created_date', 'created_time'] fields = ['sujet', 'text', 'created_by', 'created_date', 'created_time']
widgets = { widgets = {
'sujet': Select2Widget(), 'sujet': Select2Widget(),
'text': forms.Textarea(attrs={'rows':4}), 'text': forms.Textarea(
attrs={'rows': 4}
),
} }
class SimpleNoteForm(forms.ModelForm): class SimpleNoteForm(forms.ModelForm):
""" Simple note with only 'sujet' and 'text' fields. """ Simple note with only 'sujet' and 'text' fields.
@@ -30,7 +31,6 @@ class SimpleNoteForm(forms.ModelForm):
fields = ['sujet', 'text'] fields = ['sujet', 'text']
class UserNoteForm(NoteForm): class UserNoteForm(NoteForm):
""" Form that sets 'created_by' with current user id. """ Form that sets 'created_by' with current user id.
@@ -56,7 +56,6 @@ class UserNoteForm(NoteForm):
return instance return instance
class AutoNoteForm(UserNoteForm): class AutoNoteForm(UserNoteForm):
class Meta(UserNoteForm.Meta): class Meta(UserNoteForm.Meta):
fields = ['text'] fields = ['text']
@@ -73,21 +72,21 @@ class AutoNoteForm(UserNoteForm):
return inst return inst
# SUJETS
### SUJETS
current_year = datetime.date.today().year current_year = datetime.date.today().year
YEAR_CHOICE = tuple(year - 2 for year in range(current_year, current_year + 10)) YEAR_CHOICE = tuple(year - 2 for year in range(current_year, current_year + 10))
class SujetCreateForm(forms.ModelForm): class SujetCreateForm(forms.ModelForm):
class Meta: class Meta:
model = Sujet model = Sujet
fields = ['nom', 'surnom', 'prenom', 'genre', 'premiere_rencontre'] fields = ['nom', 'surnom', 'prenom', 'genre', 'premiere_rencontre']
widgets = { widgets = {'premiere_rencontre': forms.SelectDateWidget(
'premiere_rencontre': forms.SelectDateWidget( empty_label=("Année", "Mois", "Jour"), empty_label=("Année", "Mois", "Jour"),
years = YEAR_CHOICE, years=YEAR_CHOICE,
), ),
} }
class SelectSujetForm(forms.Form): class SelectSujetForm(forms.Form):

View File

@@ -5,10 +5,7 @@ from django.db.models.query import QuerySet
class NoteQuerySet(QuerySet): class NoteQuerySet(QuerySet):
def _ordered_by_field(self, field, reverse=False): def _ordered_by_field(self, field, reverse=False):
return self.order_by( '%s%s' % ( "-" if reverse else "", return self.order_by('%s%s' % ("-" if reverse else "", field))
field
)
)
def by_date(self, reverse=False): def by_date(self, reverse=False):
return self._ordered_by_field('created_date', reverse=reverse) return self._ordered_by_field('created_date', reverse=reverse)
@@ -16,6 +13,7 @@ class NoteQuerySet(QuerySet):
def by_time(self, reverse=False): def by_time(self, reverse=False):
return self._ordered_by_field('created_time', reverse=reverse) return self._ordered_by_field('created_time', reverse=reverse)
class NoteManager(Manager): class NoteManager(Manager):
def get_queryset(self): def get_queryset(self):
@@ -28,5 +26,3 @@ class NoteManager(Manager):
def by_time(self, **kwargs): def by_time(self, **kwargs):
return self.get_queryset().by_time(**kwargs) return self.get_queryset().by_time(**kwargs)

View File

@@ -1,34 +1,39 @@
from django.views.generic.edit import FormMixin from django.views.generic.edit import FormMixin
from django.contrib import messages from django.contrib import messages
from .forms import *
class NoteFormMixin(FormMixin): class NoteFormMixin(FormMixin):
""" A mixin that allows to easily embed multiple distinct forms on a view.
Only one form can be processed by request !
"""
# 'forms' shall be a dict of form classes, indexed by a prefix
forms = None forms = None
def get_form(self, prefix): def get_form_kwargs(self):
kwargs = self.get_form_kwargs() kwargs = super().get_form_kwargs()
kwargs['prefix'] = prefix
kwargs['request'] = self.request kwargs['request'] = self.request
form_class = self.forms[prefix] return kwargs
return form_class(**kwargs)
def get_form_by_prefix(self, prefix):
try:
return self.get_form(form_class=self.forms[prefix])
except KeyError:
raise ValueError("The form with prefix %s is not declared in %s" % (prefix, self.forms))
def post(self, request, **kwargs): def post(self, request, **kwargs):
""" Save the first valid form found or reload page displaying a warning """
for prefix in self.forms.keys(): for prefix in self.forms.keys():
form = self.get_form(prefix) form = self.get_form_by_prefix(prefix)
if form.is_valid(): if form.is_valid():
form.save() form.save()
messages.success(self.request, "Un nouveau %s a été enregistré" % prefix)
return self.form_valid(form) return self.form_valid(form)
return self.form_invalid(form) messages.warning(request, "Il y a eu une erreur lors du traitement du formulaire")
return self.get(request, **kwargs)
def form_valid(self, form):
messages.success(self.request, "Un nouveau %s a été enregistré" % form.prefix)
return super().form_valid(form)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(FormMixin, self).get_context_data(**kwargs) context = super(FormMixin, self).get_context_data(**kwargs)
for prefix in self.forms.keys(): for prefix in self.forms.keys():
context['%s_form' % prefix] = self.get_form(prefix) context['%s_form' % prefix] = self.get_form_by_prefix(prefix)
return context return context

View File

@@ -16,6 +16,7 @@ GENRE_CHOICES = (
(FEMME, 'Femme'), (FEMME, 'Femme'),
) )
class Sujet(models.Model): class Sujet(models.Model):
""" Personne faisant l'objet d'un suivi par la maraude """ Personne faisant l'objet d'un suivi par la maraude
""" """
@@ -38,9 +39,12 @@ class Sujet(models.Model):
def __str__(self): def __str__(self):
string = '%s ' % self.genre string = '%s ' % self.genre
if self.nom: string += '%s ' % self.nom if self.nom:
if self.surnom: string += '"%s" ' % self.surnom string += '%s ' % self.nom
if self.prenom: string += '%s' % self.prenom if self.surnom:
string += '"%s" ' % self.surnom
if self.prenom:
string += '%s' % self.prenom
return string return string
def clean(self): def clean(self):
@@ -65,6 +69,27 @@ class Sujet(models.Model):
return reverse("notes:details-sujet", kwargs={"pk": self.pk}) return reverse("notes:details-sujet", kwargs={"pk": self.pk})
# Attributes used by 'notes' template tags
# bg_color : background color of header
# labels : list of strings to put in labels
def cached_attr(name):
""" Cached property set on return value of 'note_ATTR' method on
child instance.
"""
private_name = '_%s' % name
def getter(self):
if not hasattr(self, private_name):
setattr(self,
private_name,
# Call *child instance* method
getattr(self.cast(), 'note_%s' % name)()
)
return getattr(self, private_name)
return getter
class Note(models.Model): class Note(models.Model):
""" Note relative à un sujet. """ Note relative à un sujet.
@@ -121,7 +146,7 @@ class Note(models.Model):
""" Returns (header background color, labels color). """ Returns (header background color, labels color).
Values must be valid bootstrap color name Values must be valid bootstrap color name
""" """
return ("default", "info") return "default", "info"
def note_labels(self): def note_labels(self):
""" Returns list of objects that are printed as bootstrap labels """ """ Returns list of objects that are printed as bootstrap labels """
@@ -144,7 +169,6 @@ class Note(models.Model):
self._child_class = self._child_instance.__class__ self._child_class = self._child_instance.__class__
return return
@property @property
def type_name(self): def type_name(self):
return self.child_class.__qualname__ return self.child_class.__qualname__
@@ -160,25 +184,9 @@ class Note(models.Model):
self._get_child_class_and_instance() self._get_child_class_and_instance()
return self._child_instance return self._child_instance
## Attributes used by 'notes' template tags # Define specials properties
# bg_color : background color of header
# labels : list of strings to put in labels
def cached_attr(name):
""" Cached property set on return value of 'note_ATTR' method on
child instance.
"""
private_name = '_%s' % name
def getter(self):
if not hasattr(self, private_name):
setattr(self,
private_name,
# Call *child instance* method
getattr(self.cast(), 'note_%s' % name)()
)
return getattr(self, private_name)
return getter
bg_colors = property(cached_attr('bg_colors'), doc="background color of header") bg_colors = property(cached_attr('bg_colors'), doc="background color of header")
labels = property(cached_attr('labels'), doc="list of string to display as labels") labels = property(cached_attr('labels'), doc="list of string to display as labels")
def get_absolute_url(self): def get_absolute_url(self):
return reverse("notes:details-sujet", kwargs={"pk": self.sujet.pk}) return reverse("notes:details-sujet", kwargs={"pk": self.sujet.pk})

View File

@@ -1,16 +1,14 @@
<tr> <tr>
<th class="bg-{{bg_color}}" > <th class="bg-{{bg_color}}">
{% if link %} {% if link %}
<a href="{{link}}"><strong>{{header}}</strong></a> <a href="{{link}}"><strong>{{header}}</strong></a>
{% else %} {% else %}
<strong>{{header}}</strong> <strong>{{header}}</strong>
{% endif %} <small>{{small}}</small> {% endif %} <small>{{small}}</small>
<span class="pull-right"> <br />
{% for label in labels %} {% for label in labels %}
<span class="label label-{{bg_label_color}}">{{label}}</span> <span class="label label-{{bg_label_color}}">{{label}}</span><br />
{% endfor %}</span> {% endfor %}
</th> </th>
</tr>
<tr>
<td style="background-color:#fff"><p>{{text | linebreaks }}</p></td> <td style="background-color:#fff"><p>{{text | linebreaks }}</p></td>
</tr> </tr>

View File

@@ -1,8 +1,8 @@
from django import template from django import template
from django.urls import reverse
register = template.Library() register = template.Library()
@register.inclusion_tag("notes/table_inline.html") @register.inclusion_tag("notes/table_inline.html")
def inline_table(note, header=None): def inline_table(note, header=None):
from maraudes.models import Maraude from maraudes.models import Maraude
@@ -10,7 +10,7 @@ def inline_table(note, header=None):
if not header: if not header:
header = "date" header = "date"
if not header in ['sujet', 'date']: if header not in ['sujet', 'date']:
raise ValueError('header must be "sujet" or "date"') raise ValueError('header must be "sujet" or "date"')
if header == "date": if header == "date":
@@ -24,10 +24,8 @@ def inline_table(note, header=None):
header_field = "sujet" header_field = "sujet"
link = note.sujet.get_absolute_url() link = note.sujet.get_absolute_url()
header = getattr(note, header_field)
return { return {
'header': header, 'header': getattr(note, header_field),
'link': link, 'link': link,
'small': note.child_class.__qualname__, 'small': note.child_class.__qualname__,
'bg_color': bg_color or "default", 'bg_color': bg_color or "default",

View File

@@ -24,6 +24,7 @@ class SujetModelTestCase(TestCase):
with self.assertRaises(ValidationError): with self.assertRaises(ValidationError):
Sujet.objects.create(age=25) Sujet.objects.create(age=25)
class NoteManagerTestCase(TestCase): class NoteManagerTestCase(TestCase):
""" managers.NoteManager Test Case """ """ managers.NoteManager Test Case """
@@ -32,8 +33,11 @@ class NoteManagerTestCase(TestCase):
self.note_manager = NoteManager self.note_manager = NoteManager
def test_note_default_manager_is_NoteManager(self): def test_note_default_manager_is_NoteManager(self):
self.assertIsInstance(Note.objects, self.note_manager, self.assertIsInstance(
msg="%s is not Note default manager" % self.note_manager) Note.objects,
self.note_manager,
msg="%s is not Note default manager" % self.note_manager
)
def test_by_date(self): def test_by_date(self):
prev_note = None prev_note = None
@@ -41,8 +45,11 @@ class NoteManagerTestCase(TestCase):
if not prev_note: if not prev_note:
prev_note = note prev_note = note
else: else:
self.assertLessEqual(prev_note.created_date, note.created_date, self.assertLessEqual(
msg="%s is not same date or prior to %s" % (prev_note, note)) prev_note.created_date,
note.created_date,
msg="%s is not same date or prior to %s" % (prev_note, note)
)
prev_note = note prev_note = note
def test_by_date_reversed(self): def test_by_date_reversed(self):
@@ -51,8 +58,11 @@ class NoteManagerTestCase(TestCase):
if not prev_note: if not prev_note:
prev_note = note prev_note = note
else: else:
self.assertGreaterEqual(prev_note.created_date, note.created_date, self.assertGreaterEqual(
msg="%s is not same date or later to %s" % (prev_note, note)) prev_note.created_date,
note.created_date,
msg="%s is not same date or later to %s" % (prev_note, note)
)
prev_note = note prev_note = note
def test_by_time(self): def test_by_time(self):
@@ -61,8 +71,11 @@ class NoteManagerTestCase(TestCase):
if not prev_note: if not prev_note:
prev_note = note prev_note = note
else: else:
self.assertLessEqual(prev_note.created_time, note.created_time, self.assertLessEqual(
msg="%s is not same time or prior to %s" % (prev_note, note)) prev_note.created_time,
note.created_time,
msg="%s is not same time or prior to %s" % (prev_note, note)
)
prev_note = note prev_note = note
def test_by_time_reversed(self): def test_by_time_reversed(self):
@@ -71,10 +84,13 @@ class NoteManagerTestCase(TestCase):
if not prev_note: if not prev_note:
prev_note = note prev_note = note
else: else:
self.assertLessEqual(prev_note.created_time, note.created_time, self.assertLessEqual(
msg="%s is not same time or later to %s" % (prev_note, note)) prev_note.created_time,
note.created_time,
msg="%s is not same time or later to %s" % (prev_note, note))
prev_note = note prev_note = note
class NoteQuerySetTestCase(TestCase): class NoteQuerySetTestCase(TestCase):
def setUp(self): def setUp(self):
@@ -86,7 +102,9 @@ class NoteQuerySetTestCase(TestCase):
if not prev_note: if not prev_note:
prev_note = note prev_note = note
else: else:
self.assertLessEqual(prev_note.created_date, note.created_date, self.assertLessEqual(
prev_note.created_date,
note.created_date,
msg="%s is not same date or prior to %s" % (prev_note, note)) msg="%s is not same date or prior to %s" % (prev_note, note))
prev_note = note prev_note = note
@@ -96,8 +114,11 @@ class NoteQuerySetTestCase(TestCase):
if not prev_note: if not prev_note:
prev_note = note prev_note = note
else: else:
self.assertGreaterEqual(prev_note.created_date, note.created_date, self.assertGreaterEqual(
msg="%s is not same date or later to %s" % (prev_note, note)) prev_note.created_date,
note.created_date,
msg="%s is not same date or later to %s" % (prev_note, note)
)
prev_note = note prev_note = note
def test_by_time(self): def test_by_time(self):
@@ -106,8 +127,11 @@ class NoteQuerySetTestCase(TestCase):
if not prev_note: if not prev_note:
prev_note = note prev_note = note
else: else:
self.assertLessEqual(prev_note.created_time, note.created_time, self.assertLessEqual(
msg="%s is not same time or prior to %s" % (prev_note, note)) prev_note.created_time,
note.created_time,
msg="%s is not same time or prior to %s" % (prev_note, note)
)
prev_note = note prev_note = note
def test_by_time_reversed(self): def test_by_time_reversed(self):
@@ -116,6 +140,9 @@ class NoteQuerySetTestCase(TestCase):
if not prev_note: if not prev_note:
prev_note = note prev_note = note
else: else:
self.assertLessEqual(prev_note.created_time, note.created_time, self.assertLessEqual(
msg="%s is not same time or later to %s" % (prev_note, note)) prev_note.created_time,
note.created_time,
msg="%s is not same time or later to %s" % (prev_note, note)
)
prev_note = note prev_note = note

View File

@@ -1,13 +1,12 @@
import logging import logging
import datetime import datetime
from django.shortcuts import redirect, reverse from django.shortcuts import redirect, reverse
from django.views import generic from django.views import generic
from django.utils import timezone from django.utils import timezone
from django.contrib import messages from django.contrib import messages
from django.http.response import HttpResponseNotAllowed
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from watson import search as watson
from website.mixins import AjaxTemplateMixin
from utilisateurs.mixins import MaraudeurMixin from utilisateurs.mixins import MaraudeurMixin
from maraudes.models import Maraude, CompteRendu from maraudes.models import Maraude, CompteRendu
from maraudes.notes import Observation, Signalement from maraudes.notes import Observation, Signalement
@@ -20,13 +19,13 @@ logger = logging.getLogger(__name__)
# Create your views here. # Create your views here.
class IndexView(MaraudeurMixin, generic.TemplateView): class IndexView(MaraudeurMixin, generic.TemplateView):
template_name = "notes/index.html" template_name = "notes/index.html"
def get(self, *args, **kwargs): def get(self, *args, **kwargs):
return redirect("notes:liste-sujet") return redirect("notes:liste-sujet")
class Filter: class Filter:
def __init__(self, title, name, filter_func): def __init__(self, title, name, filter_func):
self.title = title self.title = title
@@ -38,7 +37,6 @@ class Filter:
return self._filter_func(qs) return self._filter_func(qs)
class ListView(MaraudeurMixin, generic.ListView): class ListView(MaraudeurMixin, generic.ListView):
""" Base ListView for Maraude and Sujet lists """ """ Base ListView for Maraude and Sujet lists """
paginate_by = 30 paginate_by = 30
@@ -47,8 +45,8 @@ class ListView(MaraudeurMixin, generic.ListView):
filters = [] filters = []
active_filter = None active_filter = None
def __init__(self, *args, **kwargs): def __init__(self, **kwargs):
super().__init__(*args, **kwargs) super().__init__(**kwargs)
self._filters = {} self._filters = {}
if self.filters: if self.filters:
@@ -95,38 +93,37 @@ class MaraudeListView(ListView):
class SujetListView(ListView): class SujetListView(ListView):
#ListView # ListView
model = Sujet model = Sujet
template_name = "notes/liste_sujets.html" template_name = "notes/liste_sujets.html"
cell_template = "notes/table_cell_sujets.html" cell_template = "notes/table_cell_sujets.html"
table_header = "Liste des sujets" table_header = "Liste des sujets"
@staticmethod
def info_completed_filter(qs): def info_completed_filter(qs):
COMPLETED_RATIO = 70 # % of total fields completed completed_ratio = 70 # % of total fields completed
excluded_set = set() excluded_set = set()
for sujet in qs: for sujet in qs:
if sujet.statistiques.info_completed >= COMPLETED_RATIO: if sujet.statistiques.info_completed >= completed_ratio:
excluded_set.add(sujet.pk) excluded_set.add(sujet.pk)
return qs.exclude(pk__in=excluded_set) return qs.exclude(pk__in=excluded_set)
@staticmethod
def rencontre_dans_le_mois(qs): def rencontre_dans_le_mois(qs):
""" Renvoie les sujets du queryset pour lesquelles une observation a été enregistrée """ Renvoie les sujets du queryset pour lesquelles une observation a été enregistrée
au cours des 30 derniers jours """ au cours des 30 derniers jours """
DAYS_NUMBER = 30 days_number = 30
LIMIT_DATE = timezone.now().date() - datetime.timedelta(DAYS_NUMBER) limit_date = timezone.now().date() - datetime.timedelta(days_number)
included_set = set() included_set = set()
for sujet in qs: for sujet in qs:
# Try to find an observation in the range # Try to find an observation in the range
most_recent_obs = Observation.objects.filter(sujet=sujet).order_by("-created_date").first() most_recent_obs = Observation.objects.filter(sujet=sujet).order_by("-created_date").first()
if most_recent_obs and most_recent_obs.created_date >= LIMIT_DATE: if most_recent_obs and most_recent_obs.created_date >= limit_date:
included_set.add(sujet.pk) included_set.add(sujet.pk)
return qs.filter(pk__in=included_set) return qs.filter(pk__in=included_set)
filters = [ filters = [
("Connu(e)s cette année", ("Connu(e)s cette année",
lambda qs: qs.filter( lambda qs: qs.filter(
@@ -138,10 +135,9 @@ class SujetListView(ListView):
] ]
def post(self, request, **kwargs): def post(self, request, **kwargs):
from watson import search as watson
search_text = request.POST.get('q') search_text = request.POST.get('q')
results = watson.filter(Sujet, search_text) results = watson.filter(Sujet, search_text)
#logger.warning("SEARCH for %s : %s" % (search_text, results)) # logger.warning("SEARCH for %s : %s" % (search_text, results))
if results.count() == 1: if results.count() == 1:
return redirect(results[0].get_absolute_url()) return redirect(results[0].get_absolute_url())
self.queryset = results self.queryset = results
@@ -156,6 +152,7 @@ class SujetListView(ListView):
class DetailView(MaraudeurMixin, generic.DetailView): class DetailView(MaraudeurMixin, generic.DetailView):
template_name = "notes/details.html" template_name = "notes/details.html"
class CompteRenduDetailsView(DetailView): class CompteRenduDetailsView(DetailView):
""" Vue détaillé d'un compte-rendu de maraude """ """ Vue détaillé d'un compte-rendu de maraude """
@@ -165,32 +162,38 @@ class CompteRenduDetailsView(DetailView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
context['notes'] = sorted(Note.objects.get_queryset().filter(created_date=self.object.date), key=lambda n: n.created_time) context['notes'] = sorted(Note.objects
.get_queryset()
.filter(created_date=self.object.date),
key=lambda n: n.created_time)
context['next_maraude'] = Maraude.objects.get_future( context['next_maraude'] = Maraude.objects.get_future(
date=self.object.date + datetime.timedelta(1) date=self.object.date + datetime.timedelta(1)
).filter( ).filter(
heure_fin__isnull=False heure_fin__isnull=False
).first() ).first()
context['prev_maraude'] = Maraude.objects.get_past( context['prev_maraude'] = Maraude.objects.get_past(
date=self.object.date date=self.object.date
).filter( ).filter(
heure_fin__isnull=False heure_fin__isnull=False
).last() ).last()
return context return context
class SuiviSujetView(NoteFormMixin, DetailView): class SuiviSujetView(NoteFormMixin, DetailView):
#NoteFormMixin # NoteFormMixin
forms = { forms = {
'note': AutoNoteForm, 'note': AutoNoteForm,
} }
def get_success_url(self): def get_success_url(self):
return reverse('notes:details-sujet', kwargs={'pk': self.get_object().pk}) return reverse('notes:details-sujet', kwargs={'pk': self.get_object().pk})
def get_form_kwargs(self): def get_form_kwargs(self):
kwargs = super().get_form_kwargs() kwargs = super().get_form_kwargs()
kwargs['sujet'] = self.get_object() kwargs['sujet'] = self.get_object()
return kwargs return kwargs
#DetailView
# DetailView
model = Sujet model = Sujet
template_name = "notes/details_sujet.html" template_name = "notes/details_sujet.html"
context_object_name = "sujet" context_object_name = "sujet"
@@ -205,8 +208,8 @@ class SuiviSujetView(NoteFormMixin, DetailView):
self.page = self.request.GET.get('page', 1) self.page = self.request.GET.get('page', 1)
return super().get(*args, **kwargs) return super().get(*args, **kwargs)
def get_context_data(self, *args, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(*args, **kwargs) context = super().get_context_data(**kwargs)
try: try:
notes = self.paginator.page(self.page) notes = self.paginator.page(self.page)
except PageNotAnInteger: except PageNotAnInteger:
@@ -217,10 +220,9 @@ class SuiviSujetView(NoteFormMixin, DetailView):
return context return context
### Sujet Management Views # Sujet Management Views
class SujetAjaxDetailsView(generic.DetailView): class SujetAjaxDetailsView(generic.DetailView):
#DetailView # DetailView
template_name = "notes/details_sujet_inner.html" template_name = "notes/details_sujet_inner.html"
model = Sujet model = Sujet
@@ -232,8 +234,9 @@ class SujetAjaxDetailsView(generic.DetailView):
return redirect("notes:details-sujet", pk=self.get_object().pk) return redirect("notes:details-sujet", pk=self.get_object().pk)
return super().get(*args, **kwargs) return super().get(*args, **kwargs)
class SujetAjaxUpdateView(generic.edit.UpdateView): class SujetAjaxUpdateView(generic.edit.UpdateView):
#UpdateView """ View for 'sujet' updates, can be retrieved by ajax requests. """
template_name = "notes/details_sujet_update.html" template_name = "notes/details_sujet_update.html"
model = Sujet model = Sujet
fields = '__all__' fields = '__all__'
@@ -241,24 +244,28 @@ class SujetAjaxUpdateView(generic.edit.UpdateView):
def get_success_url(self): def get_success_url(self):
return reverse("notes:details-sujet", kwargs={'pk': self.object.pk}) return reverse("notes:details-sujet", kwargs={'pk': self.object.pk})
from website.mixins import AjaxTemplateMixin
class SujetCreateView(AjaxTemplateMixin, generic.edit.CreateView): class SujetCreateView(AjaxTemplateMixin, generic.edit.CreateView):
#CreateView """ View for 'sujet' creation, can be retrieved by ajax requests. """
template_name = "notes/sujet_create.html" template_name = "notes/sujet_create.html"
form_class = SujetCreateForm form_class = SujetCreateForm
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
if 'next' in self.request.POST: if 'next' in self.request.POST:
self.success_url = self.request.POST["next"] self.success_url = self.request.POST["next"]
return super().post(self, request, *args, **kwargs) return super().post(self, request, *args, **kwargs)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
try: context['next'] = self.request.GET['next'] try:
except:context['next'] = None context['next'] = self.request.GET['next']
except:
context['next'] = None
return context return context
class MergeView(generic.DetailView, generic.FormView): class MergeView(generic.DetailView, generic.FormView):
""" Implement actions.merge_two as a view """ """ Merge two 'sujet' objects by implementing actions.merge_two as a view """
template_name = "notes/sujet_merge.html" template_name = "notes/sujet_merge.html"
model = Sujet model = Sujet