many fixes

This commit is contained in:
Arthur Gerbaud
2016-08-14 15:02:42 +02:00
parent 5f31b5e3f5
commit 91079e1358
7 changed files with 118 additions and 111 deletions

View File

@@ -1,7 +0,0 @@
{% if user.is_superuser %}{% load bootstrap3 %}
<li class="dropdown app-menu"><a class="dropdown-toggle" data-toggle="dropdown" href="#">Administration<b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="{% url 'sujets:create' %}">{% bootstrap_icon "plus" %} Nouveau sujet</a></li>
<li><a href="{% url 'admin:app_list' app_label='sujets' %}">{% bootstrap_icon "wrench" %} Gérer les sujets</a></li>
</ul>
{% endif %}

View File

@@ -2,4 +2,10 @@
<li class="dropdown app-menu"><a class="dropdown-toggle" data-toggle="dropdown" href="#">Sujets<b class="caret"></b></a> <li class="dropdown app-menu"><a class="dropdown-toggle" data-toggle="dropdown" href="#">Sujets<b class="caret"></b></a>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li><a href="{% url 'sujets:liste' %}">{% bootstrap_icon "list" %} Liste complète</a></li> <li><a href="{% url 'sujets:liste' %}">{% bootstrap_icon "list" %} Liste complète</a></li>
{% if user.is_superuser %}{% load bootstrap3 %}
<li class="dropdown-header">Administration</li>
<li><a href="{% url 'sujets:create' %}">{% bootstrap_icon "plus" %} Nouveau sujet</a></li>
<li><a href="{% url 'admin:app_list' app_label='sujets' %}">
{% bootstrap_icon "wrench" %} Gérer les sujets</a></li>
{% endif %}
</ul> </ul>

View File

@@ -10,36 +10,36 @@ from sujets.models import Sujet
webpage = website.webpage( webpage = website.webpage(
ajax=False, ajax=False,
permissions=['sujets.view_sujets'], permissions=['sujets.view_sujets'],
app_menu=["suivi/menu_sujets.html", "suivi/menu_administration.html"] app_menu=["suivi/menu_sujets.html"]
) )
@webpage @webpage
class IndexView(generic.TemplateView): class IndexView(generic.TemplateView):
template_name = "suivi/index.html"
class PageInfo: class PageInfo:
title = "Suivi des bénéficiaires" title = "Suivi des bénéficiaires"
header = "Suivi" header = "Suivi"
header_small = "Tableau de bord" header_small = "Tableau de bord"
#TemplateView
template_name = "suivi/index.html"
def get_panels(self):
return ["suivi/panel_sujets.html", "suivi/panel_admin.html"]
from notes.mixins import NoteFormMixin from notes.mixins import NoteFormMixin
@webpage @webpage
class SuiviSujetView(NoteFormMixin, generic.DetailView): class SuiviSujetView(NoteFormMixin, generic.DetailView):
model = Sujet
template_name = "suivi/details.html"
context_object_name = "sujet"
class PageInfo: class PageInfo:
title = "Sujet - {{sujet}}" title = "Sujet - {{sujet}}"
header = "{{sujet}}" header = "{{sujet}}"
header_small = "suivi" header_small = "suivi"
#DetailView
model = Sujet
template_name = "suivi/details.html"
context_object_name = "sujet"
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.app_menu.insert(0, "sujets/menu_sujet.html")
def get_context_data(self, *args, **kwargs): def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs) context = super().get_context_data(*args, **kwargs)
context['notes'] = self.object.notes.by_date(reverse=True) context['notes'] = self.object.notes.by_date(reverse=True)

View File

@@ -1,44 +1,11 @@
from django.utils import timezone from django.utils import timezone
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.db import models from django.db import models
# Create your models here. ### Item choices
class Personne(models.Model):
""" Modèle de base d'une personne
- genre
- nom
- prénom
"""
HOMME = 'M'
FEMME = 'Mme'
GENRE_CHOICES = (
(HOMME, 'Homme'),
(FEMME, 'Femme'),
)
genre = models.CharField(max_length=3,
choices=GENRE_CHOICES,
default=HOMME)
nom = models.CharField(max_length=32, blank=True)
prenom = models.CharField(max_length=32, blank=True)
surnom = models.CharField(max_length=64, blank=True)
def __str__(self):
string = '%s ' % self.genre
if self.nom: string += '%s ' % self.nom
if self.surnom: string += '"%s" ' % self.surnom
if self.prenom: string += '%s' % self.prenom
return string
def clean(self):
if not any([self.nom, self.prenom, self.surnom]):
raise ValidationError(_("Vous devez remplir au moins un nom, prénom ou surnom"))
return super().clean()
# Item: Parcours institutionnel # Item: Parcours institutionnel
PARCOURS_INSTITUTIONNEL = "Institutionnel" PARCOURS_INSTITUTIONNEL = "Institutionnel"
@@ -81,15 +48,49 @@ RESSOURCES_CHOICES = (
) )
from django.db import models
### Models
# - Personne
# - Sujet
class Personne(models.Model):
""" Modèle de base d'une personne
- genre
- nom
- prénom
"""
HOMME = 'M'
FEMME = 'Mme'
GENRE_CHOICES = (
(HOMME, 'Homme'),
(FEMME, 'Femme'),
)
genre = models.CharField(max_length=3,
choices=GENRE_CHOICES,
default=HOMME)
nom = models.CharField(max_length=32, blank=True)
prenom = models.CharField(max_length=32, blank=True)
surnom = models.CharField(max_length=64, blank=True)
def __str__(self):
string = '%s ' % self.genre
if self.nom: string += '%s ' % self.nom
if self.surnom: string += '"%s" ' % self.surnom
if self.prenom: string += '%s' % self.prenom
return string
def clean(self):
if not any([self.nom, self.prenom, self.surnom]):
raise ValidationError(_("Vous devez remplir au moins un nom, prénom ou surnom"))
return super().clean()
class Sujet(Personne): class Sujet(Personne):
""" Personne faisant l'objet d'un suivi par la maraude """ Personne faisant l'objet d'un suivi par la maraude
""" """
# referent = models.ForeignKey("utilisateurs.Professionnel", related_name="suivis") # referent = models.ForeignKey("utilisateurs.Professionnel", related_name="suivis")
premiere_rencontre = models.DateField(default=timezone.now) premiere_rencontre = models.DateField(default=timezone.now)
age = models.SmallIntegerField(blank=True, null=True) age = models.SmallIntegerField(blank=True, null=True)
@@ -113,7 +114,6 @@ class Sujet(Personne):
default=RESSOURCES_NR) default=RESSOURCES_NR)
connu_siao = models.NullBooleanField("Connu du SIAO ?") connu_siao = models.NullBooleanField("Connu du SIAO ?")
class Meta: class Meta:
verbose_name = "Sujet" verbose_name = "Sujet"
ordering = ('surnom', 'nom', 'prenom') ordering = ('surnom', 'nom', 'prenom')

View File

@@ -1,85 +1,77 @@
from django.shortcuts import render from django.shortcuts import render
from django.views import generic from django.views import generic
from website import decorators as website
from .models import Sujet from .models import Sujet
from .forms import SujetCreateForm
from django.forms import ModelForm ### Webpage config
from website import decorators as website
webpage = website.webpage( webpage = website.webpage(
ajax=True, ajax=True,
permissions=['sujets.view_sujets'], permissions=['sujets.view_sujets'],
app_name="suivi", app_name="suivi",
app_menu=["suivi/menu_sujets.html", "suivi/menu_administration.html"] app_menu=["sujets/menu_sujet.html"]
) )
# Create your views here. ### Views
# TODO: deal with setting an active_app name other than module name
@webpage @webpage
class SujetDetailsView(generic.DetailView): class SujetDetailsView(generic.DetailView):
template_name = "sujets/sujet_details.html"
model = Sujet
class PageInfo: class PageInfo:
title = "Sujet - {{ sujet }}" title = "Sujet - {{ sujet }}"
header = "{{ sujet }}" header = "{{ sujet }}"
header_small = "suivi" header_small = "suivi"
#DetailView
template_name = "sujets/sujet_details.html"
model = Sujet
@webpage @webpage
class SujetListView(generic.ListView): class SujetListView(generic.ListView):
model = Sujet
template_name = "sujets/sujet_liste.html"
class PageInfo: class PageInfo:
title = "Sujet - Liste des sujets" title = "Sujet - Liste des sujets"
header = "Liste des sujets" header = "Liste des sujets"
#ListView
model = Sujet
template_name = "sujets/sujet_liste.html"
paginate_by = 10
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.app_menu = ["suivi/menu_sujets.html"]
@webpage @webpage
class SujetUpdateView(generic.edit.UpdateView): class SujetUpdateView(generic.edit.UpdateView):
template_name = "sujets/sujet_update.html"
model = Sujet
fields = '__all__'
class PageInfo: class PageInfo:
title = "Mise à jour - {{sujet}}" title = "Mise à jour - {{sujet}}"
header = "{{sujet}}" header = "{{sujet}}"
header_small = "mise à jour" header_small = "mise à jour"
#UpdateView
def __init__(self, *args, **kwargs): template_name = "sujets/sujet_update.html"
super().__init__(*args, **kwargs)
print('SujetUpdateView init:', self.__class__.__bases__)
class SujetCreateForm(ModelForm):
class Meta:
model = Sujet model = Sujet
fields = ['nom', 'surnom', 'prenom', 'genre', 'premiere_rencontre'] fields = '__all__'
@webpage @webpage
class SujetCreateView(generic.edit.CreateView): class SujetCreateView(generic.edit.CreateView):
template_name = "sujets/sujet_create.html"
form_class = SujetCreateForm
class PageInfo: class PageInfo:
title = "Nouveau sujet" title = "Nouveau sujet"
header = "Nouveau sujet" header = "Nouveau sujet"
# Special permissions
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.permissions += ['sujets.add_sujet'] self.permissions += ['sujets.add_sujet']
#CreateView
template_name = "sujets/sujet_create.html"
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: try: context['next'] = self.request.GET['next']
context['next'] = self.request.GET['next'] except:context['next'] = None
except:
context['next'] = None
return context return context

View File

@@ -6,19 +6,7 @@ from django.contrib.auth.decorators import login_required, permission_required
from django.template import Template, Context from django.template import Template, Context
from django.views.generic.base import ContextMixin, TemplateResponseMixin from django.views.generic.base import ContextMixin, TemplateResponseMixin
## Utils ##
APP_ICONS = {
'maraudes': 'road',
'suivi': 'eye-open',
}
def get_apps_config(app_names):
_apps = []
for name in app_names:
app_config = apps.get_app_config(name)
app_config.menu_icon = APP_ICONS[name]
_apps.append(app_config)
return _apps
## Mixins ## ## Mixins ##
@@ -63,12 +51,12 @@ class WebsiteTemplateMixin(TemplateResponseMixin):
class Configuration: class Configuration:
stylesheets = ['base.css'] stylesheets = ['base.css']
navbar_apps = ['maraudes', 'suivi'] navbar_apps = ['maraudes', 'suivi']
apps = get_apps_config(navbar_apps)
page_blocks = ['header', 'header_small', 'title'] page_blocks = ['header', 'header_small', 'title']
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.user = None
self._page_blocks = [] self._page_blocks = []
if not hasattr(self, "PageInfo"): if not hasattr(self, "PageInfo"):
raise ImproperlyConfigured("You must define a PageInfo on ", self) raise ImproperlyConfigured("You must define a PageInfo on ", self)
@@ -86,10 +74,38 @@ class WebsiteTemplateMixin(TemplateResponseMixin):
self.content_template = self.template_name self.content_template = self.template_name
return self.content_template return self.content_template
def get_apps_config(self):
""" Load additionnal config data on each app registered in navbar"""
## Utils ##
APP_ICONS = {
'maraudes': 'road',
'suivi': 'eye-open',
}
app_names = self.Configuration.navbar_apps
self._apps = []
for name in app_names:
app_config = apps.get_app_config(name)
app_config.menu_icon = APP_ICONS[name]
#Known Issue: there is actually no 'suivi.view_suivi' permission yet !
app_config.disabled = not self.request.user.has_perm('%s.view_%s' % (name, name))
print(self.request.user, app_config, '-> has perm:', not app_config.disabled)
self._apps.append(app_config)
return self._apps
@property
def apps(self):
if not hasattr(self, '_apps'):
self._apps = self.get_apps_config()
return self._apps
def get_active_app(self): def get_active_app(self):
if not self.app_name: if not self.app_name:
self.app_name = self.__class__.__module__.split(".")[0] self.app_name = self.__class__.__module__.split(".")[0]
return apps.get_app_config(self.app_name) active_app = apps.get_app_config(self.app_name)
if not active_app in self.apps: #TODO: how do we deal with this ?
print("%s must be registered in Configuration.navbar_apps" % active_app)
return None
return active_app
@property @property
def active_app(self): def active_app(self):
@@ -122,7 +138,7 @@ class WebsiteTemplateMixin(TemplateResponseMixin):
self._update_context_with_rendered_blocks(context) self._update_context_with_rendered_blocks(context)
#Website processor #Website processor
context['stylesheets'] = self.Configuration.stylesheets context['stylesheets'] = self.Configuration.stylesheets
context['apps'] = self.Configuration.apps context['apps'] = self.apps
context['active_app'] = self.active_app context['active_app'] = self.active_app
# User processor # User processor
context = user_processor(self.request, context) context = user_processor(self.request, context)

View File

@@ -12,7 +12,7 @@
</div> </div>
<div class="collapse navbar-collapse"> <div class="collapse navbar-collapse">
<ul class="nav navbar-nav">{% for app in apps %} <ul class="nav navbar-nav">{% for app in apps %}
<li {% if app == active_app %} class="active" {%endif%}> <li class="{% if app == active_app %}active{%endif%} {% if app.disabled %}disabled{% endif%}">
<a href="/{{app.label}}/">{% bootstrap_icon app.menu_icon %} &middot; <strong>{{ app.name|title }}</strong></a> <a href="/{{app.label}}/">{% bootstrap_icon app.menu_icon %} &middot; <strong>{{ app.name|title }}</strong></a>
</li> </li>
{% if app == active_app %}{% for t in app_menu %}{% include t %}{% endfor %}{% endif %} {% if app == active_app %}{% for t in app_menu %}{% include t %}{% endfor %}{% endif %}
@@ -21,11 +21,11 @@
<ul class="nav navbar-nav navbar-right"> <ul class="nav navbar-nav navbar-right">
<li class="dropdown"> <li class="dropdown">
<a id="UserMenu" href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"> <a id="UserMenu" href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
<strong style="color:#fff;">{% bootstrap_icon "user" %} {{user}} </strong>&middot; {{ user_group }}<span class="caret"></span></a> <strong style="color:#fff;">{% bootstrap_icon "user" %} &middot; {{user}} </strong>&middot; {{ user_group }}<span class="caret"></span></a>
<ul class="dropdown-menu" aria-labelledby="UserMenu"> <ul class="dropdown-menu" aria-labelledby="UserMenu">
{% if user.is_authenticated %} {% if user.is_authenticated %}
{% if user.is_superuser %}<li><a href="/admin/">Administration {% bootstrap_icon "new-window" %} </a></li>{% endif %} {% if user.is_superuser %}<li><a href="{% url 'admin:index' %}">{% bootstrap_icon "wrench" %} Administration</a></li>{% endif %}
<li><a href="{% url 'logout' %}">Déconnecter {% bootstrap_icon "log-out" %}</a></li> <li><a href="{% url 'logout' %}">{% bootstrap_icon "log-out" %} Déconnecter</a></li>
{% else %} {% else %}
<li> <li>
<form class="navbar-form navbar-left" method="post" action="">{% csrf_token %} <form class="navbar-form navbar-left" method="post" action="">{% csrf_token %}