Merge branch 'Qwann/events/admin' into 'master'
Qwann/events/admin See merge request cof-geek/GestionEvenementiel!28
This commit is contained in:
commit
c723f53909
3 changed files with 224 additions and 5 deletions
|
@ -1,3 +1,89 @@
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
from shared.admin import admin_site
|
||||||
|
|
||||||
# Register your models here.
|
from .models import Event, Place, ActivityTag, Activity, ActivityTemplate # TODO add me
|
||||||
|
|
||||||
|
|
||||||
|
class EventAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ['title', 'slug', 'beginning_date', 'ending_date']
|
||||||
|
readonly_fields = ['created_by', 'created_at', ]
|
||||||
|
ordering = ['title', 'beginning_date', 'ending_date', ]
|
||||||
|
search_fields = ['title', 'decription', ]
|
||||||
|
list_filter = ['beginning_date', 'ending_date', ]
|
||||||
|
date_hierarchy = 'beginning_date'
|
||||||
|
|
||||||
|
|
||||||
|
class PlaceAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ['name', 'event', ]
|
||||||
|
ordering = ['name', 'event', ]
|
||||||
|
search_fields = ['name', ]
|
||||||
|
list_filter = ['event', ]
|
||||||
|
|
||||||
|
|
||||||
|
class ActivityTagAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ['name', 'event', 'is_public', ]
|
||||||
|
ordering = ['name', 'event', 'is_public', ]
|
||||||
|
search_fields = ['name', ]
|
||||||
|
list_filter = ['event', 'is_public', ]
|
||||||
|
|
||||||
|
|
||||||
|
class ActivityTemplateAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ['name', 'title', 'event', 'is_public', ]
|
||||||
|
ordering = ['name', 'title', 'event', 'has_perm', ]
|
||||||
|
search_fields = ['name', 'title', 'description', 'remark', ]
|
||||||
|
list_filter = ['event', 'is_public', 'has_perm', 'tags', ]
|
||||||
|
filter_horizontal = ['tags', 'places', ]
|
||||||
|
fieldsets = (
|
||||||
|
('Identifiant', {
|
||||||
|
'fields': ('name', ),
|
||||||
|
}),
|
||||||
|
('Général', {
|
||||||
|
'fields': ('event', 'title', 'is_public', 'places', ),
|
||||||
|
'description': "Tous ces champs sont héritables (Sauf Évènement)",
|
||||||
|
}),
|
||||||
|
('Permanences', {
|
||||||
|
'fields': ('has_perm', ('min_perm', 'max_perm', ), ),
|
||||||
|
'classes': ('collapse',),
|
||||||
|
'description': "Tous ces champs sont héritables",
|
||||||
|
}),
|
||||||
|
('Descriptions', {
|
||||||
|
'fields': ('description', 'tags', 'remarks', ),
|
||||||
|
'classes': ('collapse',),
|
||||||
|
'description': "Tous ces champs sont héritables",
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ActivityAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ['title', 'event', 'is_public', 'parent', ]
|
||||||
|
ordering = ['title', 'event', 'has_perm', 'parent', ]
|
||||||
|
search_fields = ['title', 'description', 'remark', ]
|
||||||
|
list_filter = ['event', 'is_public', 'has_perm', 'tags', ]
|
||||||
|
filter_horizontal = ['tags', 'places', ]
|
||||||
|
fieldsets = (
|
||||||
|
('Général', {
|
||||||
|
'fields': ('event', 'parent', 'title', 'is_public', 'places', ),
|
||||||
|
'description': "Tous ces champs sont héritables (sauf parent et Évènement)",
|
||||||
|
}),
|
||||||
|
('Champs non-héritables', {
|
||||||
|
'fields': ('parent', ),
|
||||||
|
'description': "Tous ces champs doivent être spécifiés",
|
||||||
|
}),
|
||||||
|
('Permanences', {
|
||||||
|
'fields': ('has_perm', ('min_perm', 'max_perm', ), ),
|
||||||
|
'classes': ('collapse',),
|
||||||
|
'description': "Tous ces champs sont héritables (sauf les gens en perm)",
|
||||||
|
}),
|
||||||
|
('Descriptions', {
|
||||||
|
'fields': ('description', 'tags', 'remarks', 'staff', ),
|
||||||
|
'classes': ('collapse',),
|
||||||
|
'description': "Tous ces champs sont héritables",
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
admin_site.register(Event, EventAdmin)
|
||||||
|
admin_site.register(Place, PlaceAdmin)
|
||||||
|
admin_site.register(ActivityTag, ActivityTagAdmin)
|
||||||
|
admin_site.register(ActivityTemplate, ActivityTemplateAdmin)
|
||||||
|
admin_site.register(Activity, ActivityAdmin)
|
||||||
|
|
32
event/migrations/0002_auto_20180820_1529.py
Normal file
32
event/migrations/0002_auto_20180820_1529.py
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.11.11 on 2018-08-20 15:29
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('event', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='activitytemplate',
|
||||||
|
name='name',
|
||||||
|
field=models.CharField(default='change_me!', help_text='Ne sera pas affiché', max_length=200, verbose_name='Nom du template'),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='activity',
|
||||||
|
name='event',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='event.Event', verbose_name='évènement'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='activitytemplate',
|
||||||
|
name='event',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='event.Event', verbose_name='évènement'),
|
||||||
|
),
|
||||||
|
]
|
109
event/models.py
109
event/models.py
|
@ -1,5 +1,5 @@
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.core.exceptions import FieldDoesNotExist, FieldError
|
from django.core.exceptions import FieldDoesNotExist, FieldError, ValidationError
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
@ -123,7 +123,6 @@ class AbstractActivityTemplate(SubscriptionMixin, models.Model):
|
||||||
Event,
|
Event,
|
||||||
verbose_name=_("évènement"),
|
verbose_name=_("évènement"),
|
||||||
on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
editable=False,
|
|
||||||
)
|
)
|
||||||
is_public = models.NullBooleanField(
|
is_public = models.NullBooleanField(
|
||||||
_("est public"),
|
_("est public"),
|
||||||
|
@ -167,12 +166,34 @@ class AbstractActivityTemplate(SubscriptionMixin, models.Model):
|
||||||
|
|
||||||
|
|
||||||
class ActivityTemplate(AbstractActivityTemplate):
|
class ActivityTemplate(AbstractActivityTemplate):
|
||||||
|
name = models.CharField(
|
||||||
|
_("Nom du template"),
|
||||||
|
max_length=200,
|
||||||
|
help_text=_("Ne sera pas affiché"),
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _("template activité")
|
verbose_name = _("template activité")
|
||||||
verbose_name_plural = _("templates activité")
|
verbose_name_plural = _("templates activité")
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.title
|
return self.name
|
||||||
|
|
||||||
|
def clean(self):
|
||||||
|
errors = []
|
||||||
|
|
||||||
|
# On clean les nombre de permanents
|
||||||
|
if not self.has_perm:
|
||||||
|
self.max_perm = None
|
||||||
|
self.min_perm = None
|
||||||
|
else:
|
||||||
|
if self.min_perm > self.max_perm:
|
||||||
|
errors.append(ValidationError(
|
||||||
|
_("Nombres de permanents incompatibles"),
|
||||||
|
code='wrong-nb-perm',
|
||||||
|
))
|
||||||
|
if errors != []:
|
||||||
|
raise ValidationError(errors)
|
||||||
|
|
||||||
|
|
||||||
class Activity(AbstractActivityTemplate):
|
class Activity(AbstractActivityTemplate):
|
||||||
|
@ -193,6 +214,86 @@ class Activity(AbstractActivityTemplate):
|
||||||
beginning = models.DateTimeField(_("heure de début"))
|
beginning = models.DateTimeField(_("heure de début"))
|
||||||
end = models.DateTimeField(_("heure de fin"))
|
end = models.DateTimeField(_("heure de fin"))
|
||||||
|
|
||||||
|
def clean(self):
|
||||||
|
errors = []
|
||||||
|
|
||||||
|
# On clean les nombre de permanents
|
||||||
|
if not self.get_herited('has_perm'):
|
||||||
|
self.max_perm = None
|
||||||
|
self.min_perm = None
|
||||||
|
else:
|
||||||
|
if self.get_herited('min_perm') > self.get_herited('max_perm'):
|
||||||
|
errors.append(ValidationError(
|
||||||
|
_("Nombres de permanents incompatibles"),
|
||||||
|
code='wrong-nb-perm',
|
||||||
|
))
|
||||||
|
|
||||||
|
# On valide l'héritage
|
||||||
|
for f in self._meta.get_fields():
|
||||||
|
try:
|
||||||
|
# On réccupère le field du parent
|
||||||
|
attrname = f.name
|
||||||
|
tpl_field = ActivityTemplate._meta.get_field(attrname)
|
||||||
|
# Peut-être que ce n'est pas un field
|
||||||
|
# concerné par l'héritage
|
||||||
|
except FieldDoesNotExist:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Y'a certains champs dont on se moque
|
||||||
|
if attrname in ['id', 'staff', 'tags', ]:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# C'est plus compliqué que ça pour les nb_perm
|
||||||
|
if attrname in ['max_perm', 'min_perm', ]:
|
||||||
|
if not self.get_herited('has_perm'):
|
||||||
|
continue
|
||||||
|
|
||||||
|
|
||||||
|
# On a un Many to Many, on lit différement
|
||||||
|
if tpl_field.many_to_many:
|
||||||
|
pass
|
||||||
|
# # On a pas spécifié
|
||||||
|
# if not value.exists():
|
||||||
|
# # On a pas de parent
|
||||||
|
# if self.parent is None:
|
||||||
|
# errors.append(ValidationError(
|
||||||
|
# _("N'hérite pas d'un template, spécifier le champs : %(attr)s"),
|
||||||
|
# code='bad-overriding',
|
||||||
|
# params={'attr': f.verbose_name},
|
||||||
|
# ))
|
||||||
|
# else:
|
||||||
|
# pvalue = getattr(self.parent, attrname)
|
||||||
|
# # On a un parent qui ne dit rien
|
||||||
|
# if not pvalue.exists():
|
||||||
|
# errors.append(ValidationError(
|
||||||
|
# _("Champs non précisé chez le parent, spécifier : %(attr)s"),
|
||||||
|
# code='bad-overriding',
|
||||||
|
# params={'attr': f.verbose_name},
|
||||||
|
# ))
|
||||||
|
else:
|
||||||
|
value = getattr(self, attrname)
|
||||||
|
# On a pas spécifié
|
||||||
|
if value is None:
|
||||||
|
# On a pas de parent
|
||||||
|
if self.parent is None:
|
||||||
|
errors.append(ValidationError(
|
||||||
|
_("N'hérite pas d'un template, spécifier le champs : %(attr)s"),
|
||||||
|
code='bad-overriding',
|
||||||
|
params={'attr': f.verbose_name},
|
||||||
|
))
|
||||||
|
else:
|
||||||
|
pvalue = getattr(self.parent, attrname)
|
||||||
|
# On a un parent qui ne dit rien
|
||||||
|
if pvalue is None:
|
||||||
|
errors.append(ValidationError(
|
||||||
|
_("Champs non précisé chez le parent, spécifier : %(attr)s"),
|
||||||
|
code='bad-overriding',
|
||||||
|
params={'attr': f.verbose_name},
|
||||||
|
))
|
||||||
|
if errors != []:
|
||||||
|
raise ValidationError(errors)
|
||||||
|
|
||||||
|
|
||||||
def get_herited(self, attrname):
|
def get_herited(self, attrname):
|
||||||
try:
|
try:
|
||||||
tpl_field = ActivityTemplate._meta.get_field(attrname)
|
tpl_field = ActivityTemplate._meta.get_field(attrname)
|
||||||
|
@ -219,4 +320,4 @@ class Activity(AbstractActivityTemplate):
|
||||||
verbose_name_plural = _("activités")
|
verbose_name_plural = _("activités")
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.get_herited('title')
|
return self.get_herited('title')
|
||||||
|
|
Loading…
Reference in a new issue