Clean some models
Add/fix some field names, verbose_name, help_text, on_delete (for foreign keys), etc.
This commit is contained in:
parent
cd4695c27a
commit
cd78757244
4 changed files with 287 additions and 104 deletions
21
equipment/migrations/0002_auto_20170802_2323.py
Normal file
21
equipment/migrations/0002_auto_20170802_2323.py
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.11.4 on 2017-08-02 23:23
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('equipment', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='equipment',
|
||||||
|
name='event',
|
||||||
|
field=models.ForeignKey(blank=True, help_text="Si spécifié, l'instance du modèle est spécifique à l'évènement en question.", null=True, on_delete=django.db.models.deletion.CASCADE, to='event.Event', verbose_name='évènement'),
|
||||||
|
),
|
||||||
|
]
|
136
event/migrations/0004_auto_20170802_2323.py
Normal file
136
event/migrations/0004_auto_20170802_2323.py
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.11.4 on 2017-08-02 23:23
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
import django.core.validators
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('event', '0003_auto_20170726_1116'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='activity',
|
||||||
|
name='place',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='activitytemplate',
|
||||||
|
name='place',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='activity',
|
||||||
|
name='places',
|
||||||
|
field=models.ManyToManyField(blank=True, to='event.Place', verbose_name='lieux'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='activitytemplate',
|
||||||
|
name='places',
|
||||||
|
field=models.ManyToManyField(blank=True, to='event.Place', verbose_name='lieux'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='activity',
|
||||||
|
name='description',
|
||||||
|
field=models.TextField(blank=True, help_text="Visible par tout le monde si l'événément est public.", null=True, verbose_name='description'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='activity',
|
||||||
|
name='event',
|
||||||
|
field=models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, to='event.Event', verbose_name='évènement'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='activity',
|
||||||
|
name='has_perm',
|
||||||
|
field=models.NullBooleanField(verbose_name='inscription de permanents'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='activity',
|
||||||
|
name='is_public',
|
||||||
|
field=models.NullBooleanField(verbose_name='est public'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='activity',
|
||||||
|
name='parent',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='children', to='event.ActivityTemplate', verbose_name='template'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='activity',
|
||||||
|
name='remarks',
|
||||||
|
field=models.TextField(blank=True, help_text='Visible uniquement par les organisateurs.', null=True, verbose_name='remarques'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='activity',
|
||||||
|
name='staff',
|
||||||
|
field=models.ManyToManyField(blank=True, related_name='in_perm_activities', to=settings.AUTH_USER_MODEL, verbose_name='permanents'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='activity',
|
||||||
|
name='tags',
|
||||||
|
field=models.ManyToManyField(blank=True, to='event.ActivityTag', verbose_name='tags'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='activitytag',
|
||||||
|
name='color',
|
||||||
|
field=models.CharField(help_text='Rentrer une couleur en hexadécimal (#XXX ou #XXXXXX).', max_length=7, validators=[django.core.validators.RegexValidator(message="La chaîne de caractère rentrée n'est pas une couleur en hexadécimal.", regex='^#(?:[0-9a-fA-F]{3}){1,2}$')], verbose_name='couleur'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='activitytag',
|
||||||
|
name='event',
|
||||||
|
field=models.ForeignKey(blank=True, help_text="Si spécifié, l'instance du modèle est spécifique à l'évènement en question.", null=True, on_delete=django.db.models.deletion.CASCADE, to='event.Event', verbose_name='évènement'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='activitytag',
|
||||||
|
name='is_public',
|
||||||
|
field=models.BooleanField(help_text="Sert à faire une distinction dans l'affichage selon que le tag soit destiné au public ou à l'organisation.", verbose_name='est public'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='activitytemplate',
|
||||||
|
name='description',
|
||||||
|
field=models.TextField(blank=True, help_text="Visible par tout le monde si l'événément est public.", null=True, verbose_name='description'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='activitytemplate',
|
||||||
|
name='event',
|
||||||
|
field=models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, to='event.Event', verbose_name='évènement'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='activitytemplate',
|
||||||
|
name='has_perm',
|
||||||
|
field=models.NullBooleanField(verbose_name='inscription de permanents'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='activitytemplate',
|
||||||
|
name='is_public',
|
||||||
|
field=models.NullBooleanField(verbose_name='est public'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='activitytemplate',
|
||||||
|
name='remarks',
|
||||||
|
field=models.TextField(blank=True, help_text='Visible uniquement par les organisateurs.', null=True, verbose_name='remarques'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='activitytemplate',
|
||||||
|
name='tags',
|
||||||
|
field=models.ManyToManyField(blank=True, to='event.ActivityTag', verbose_name='tags'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='event',
|
||||||
|
name='created_by',
|
||||||
|
field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='created_events', to=settings.AUTH_USER_MODEL, verbose_name='créé par'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='event',
|
||||||
|
name='slug',
|
||||||
|
field=models.SlugField(help_text="Seulement des lettres, des chiffres ou les caractères '_' ou '-'.", unique=True, verbose_name='identificateur'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='place',
|
||||||
|
name='event',
|
||||||
|
field=models.ForeignKey(blank=True, help_text="Si spécifié, l'instance du modèle est spécifique à l'évènement en question.", null=True, on_delete=django.db.models.deletion.CASCADE, to='event.Event', verbose_name='évènement'),
|
||||||
|
),
|
||||||
|
]
|
224
event/models.py
224
event/models.py
|
@ -1,36 +1,48 @@
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.utils.translation import ugettext_lazy as _
|
|
||||||
from django.core.validators import RegexValidator
|
from django.core.validators import RegexValidator
|
||||||
from django.core.exceptions import FieldError
|
from django.core.exceptions import FieldDoesNotExist, FieldError
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from communication.models import SubscriptionMixin
|
from communication.models import SubscriptionMixin
|
||||||
|
|
||||||
User = get_user_model()
|
User = get_user_model()
|
||||||
|
|
||||||
|
|
||||||
|
ColorValidator = RegexValidator(
|
||||||
|
regex=r'^#(?:[0-9a-fA-F]{3}){1,2}$',
|
||||||
|
message=_(
|
||||||
|
"La chaîne de caractère rentrée n'est pas une couleur en hexadécimal."
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class Event(SubscriptionMixin, models.Model):
|
class Event(SubscriptionMixin, models.Model):
|
||||||
title = models.CharField(
|
title = models.CharField(
|
||||||
_("nom de l'évènement"),
|
_("nom de l'évènement"),
|
||||||
max_length=200,
|
max_length=200,
|
||||||
)
|
)
|
||||||
slug = models.SlugField(
|
slug = models.SlugField(
|
||||||
_('identificateur'),
|
_("identificateur"),
|
||||||
unique=True,
|
unique=True,
|
||||||
help_text=_("Seulement des lettres, des chiffres ou"
|
help_text=_(
|
||||||
"les caractères '_' ou '-'."),
|
"Seulement des lettres, des chiffres ou les caractères '_' ou '-'."
|
||||||
)
|
),
|
||||||
|
)
|
||||||
created_by = models.ForeignKey(
|
created_by = models.ForeignKey(
|
||||||
User,
|
User,
|
||||||
related_name="created_events",
|
verbose_name=_("créé par"),
|
||||||
editable=False,
|
on_delete=models.SET_NULL,
|
||||||
)
|
related_name="created_events",
|
||||||
|
editable=False, null=True,
|
||||||
|
)
|
||||||
created_at = models.DateTimeField(
|
created_at = models.DateTimeField(
|
||||||
_('date de création'),
|
_("date de création"),
|
||||||
auto_now_add=True,
|
auto_now_add=True,
|
||||||
)
|
)
|
||||||
description = models.TextField(_('description'))
|
description = models.TextField(_("description"))
|
||||||
beginning_date = models.DateTimeField(_('date de début'))
|
beginning_date = models.DateTimeField(_("date de début"))
|
||||||
ending_date = models.DateTimeField(_('date de fin'))
|
ending_date = models.DateTimeField(_("date de fin"))
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _("évènement")
|
verbose_name = _("évènement")
|
||||||
|
@ -45,12 +57,14 @@ class EventSpecificMixin(models.Model):
|
||||||
or not (depending on whether the event field is null)"""
|
or not (depending on whether the event field is null)"""
|
||||||
|
|
||||||
event = models.ForeignKey(
|
event = models.ForeignKey(
|
||||||
'event.Event',
|
Event,
|
||||||
verbose_name=_("évènement"),
|
verbose_name=_("évènement"),
|
||||||
help_text=_("Si spécifié, l'instance du modèle "
|
help_text=_(
|
||||||
"est spécifique à l'évènement en question"),
|
"Si spécifié, l'instance du modèle est spécifique à l'évènement "
|
||||||
blank=True,
|
"en question."
|
||||||
null=True
|
),
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
blank=True, null=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -59,9 +73,9 @@ class EventSpecificMixin(models.Model):
|
||||||
|
|
||||||
class Place(EventSpecificMixin, models.Model):
|
class Place(EventSpecificMixin, models.Model):
|
||||||
name = models.CharField(
|
name = models.CharField(
|
||||||
_("nom du lieu"),
|
_("nom du lieu"),
|
||||||
max_length=200,
|
max_length=200,
|
||||||
)
|
)
|
||||||
description = models.TextField(blank=True)
|
description = models.TextField(blank=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -74,26 +88,22 @@ class Place(EventSpecificMixin, models.Model):
|
||||||
|
|
||||||
class ActivityTag(EventSpecificMixin, models.Model):
|
class ActivityTag(EventSpecificMixin, models.Model):
|
||||||
name = models.CharField(
|
name = models.CharField(
|
||||||
_("nom du tag"),
|
_("nom du tag"),
|
||||||
max_length=200,
|
max_length=200,
|
||||||
)
|
)
|
||||||
is_public = models.BooleanField(
|
is_public = models.BooleanField(
|
||||||
help_text=_("Sert à faire une distinction dans"
|
_("est public"),
|
||||||
" l'affichage selon que cela soit"
|
help_text=_(
|
||||||
" destiné au public ou à l'équipe"
|
"Sert à faire une distinction dans l'affichage selon que le tag "
|
||||||
" organisatrice"),
|
"soit destiné au public ou à l'organisation."
|
||||||
)
|
),
|
||||||
color_regex = RegexValidator(
|
)
|
||||||
regex=r'^#(?:[0-9a-fA-F]{3}){1,2}$',
|
|
||||||
message=_("La chaîne de caractère rentrée n'est pas"
|
|
||||||
" une couleur en hexadécimal."),
|
|
||||||
)
|
|
||||||
color = models.CharField(
|
color = models.CharField(
|
||||||
_('couleur'),
|
_('couleur'),
|
||||||
max_length=7,
|
max_length=7,
|
||||||
validators=[color_regex],
|
validators=[ColorValidator],
|
||||||
help_text=_("Rentrer une couleur en hexadécimal"),
|
help_text=_("Rentrer une couleur en hexadécimal (#XXX ou #XXXXXX)."),
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _("tag")
|
verbose_name = _("tag")
|
||||||
|
@ -105,49 +115,53 @@ class ActivityTag(EventSpecificMixin, models.Model):
|
||||||
|
|
||||||
class AbstractActivityTemplate(SubscriptionMixin, models.Model):
|
class AbstractActivityTemplate(SubscriptionMixin, models.Model):
|
||||||
title = models.CharField(
|
title = models.CharField(
|
||||||
_("nom de l'activité"),
|
_("nom de l'activité"),
|
||||||
max_length=200,
|
max_length=200,
|
||||||
blank=True,
|
blank=True, null=True,
|
||||||
null=True,
|
)
|
||||||
)
|
|
||||||
# FIXME: voir comment on traite l'héritage de `event`
|
# FIXME: voir comment on traite l'héritage de `event`
|
||||||
event = models.ForeignKey(Event)
|
event = models.ForeignKey(
|
||||||
|
Event,
|
||||||
|
verbose_name=_("évènement"),
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
editable=False,
|
||||||
|
)
|
||||||
is_public = models.NullBooleanField(
|
is_public = models.NullBooleanField(
|
||||||
blank=True,
|
_("est public"),
|
||||||
)
|
blank=True,
|
||||||
|
)
|
||||||
has_perm = models.NullBooleanField(
|
has_perm = models.NullBooleanField(
|
||||||
blank=True,
|
_("inscription de permanents"),
|
||||||
)
|
blank=True,
|
||||||
|
)
|
||||||
min_perm = models.PositiveSmallIntegerField(
|
min_perm = models.PositiveSmallIntegerField(
|
||||||
_('nombre minimum de permanents'),
|
_('nombre minimum de permanents'),
|
||||||
blank=True,
|
blank=True, null=True,
|
||||||
null=True,
|
)
|
||||||
)
|
|
||||||
max_perm = models.PositiveSmallIntegerField(
|
max_perm = models.PositiveSmallIntegerField(
|
||||||
_('nombre maximum de permanents'),
|
_('nombre maximum de permanents'),
|
||||||
blank=True,
|
blank=True, null=True,
|
||||||
null=True,
|
)
|
||||||
)
|
|
||||||
description = models.TextField(
|
description = models.TextField(
|
||||||
_('description'),
|
_('description'),
|
||||||
help_text=_("Public, Visible par tout le monde."),
|
help_text=_("Visible par tout le monde si l'événément est public."),
|
||||||
blank=True,
|
blank=True, null=True,
|
||||||
null=True,
|
)
|
||||||
)
|
|
||||||
remarks = models.TextField(
|
remarks = models.TextField(
|
||||||
_('remarques'),
|
_('remarques'),
|
||||||
help_text=_("Visible uniquement par les organisateurs"),
|
help_text=_("Visible uniquement par les organisateurs."),
|
||||||
blank=True,
|
blank=True, null=True,
|
||||||
null=True,
|
)
|
||||||
)
|
|
||||||
tags = models.ManyToManyField(
|
tags = models.ManyToManyField(
|
||||||
ActivityTag,
|
ActivityTag,
|
||||||
blank=True,
|
verbose_name=_('tags'),
|
||||||
)
|
blank=True,
|
||||||
place = models.ManyToManyField(
|
)
|
||||||
Place,
|
places = models.ManyToManyField(
|
||||||
blank=True,
|
Place,
|
||||||
)
|
verbose_name=_('lieux'),
|
||||||
|
blank=True,
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
abstract = True
|
||||||
|
@ -164,40 +178,42 @@ class ActivityTemplate(AbstractActivityTemplate):
|
||||||
|
|
||||||
class Activity(AbstractActivityTemplate):
|
class Activity(AbstractActivityTemplate):
|
||||||
parent = models.ForeignKey(
|
parent = models.ForeignKey(
|
||||||
ActivityTemplate,
|
ActivityTemplate,
|
||||||
related_name="children",
|
verbose_name=_("template"),
|
||||||
blank=True,
|
on_delete=models.PROTECT,
|
||||||
null=True,
|
related_name="children",
|
||||||
)
|
blank=True, null=True,
|
||||||
|
)
|
||||||
staff = models.ManyToManyField(
|
staff = models.ManyToManyField(
|
||||||
User,
|
User,
|
||||||
related_name="in_perm_activities",
|
verbose_name=_("permanents"),
|
||||||
blank=True,
|
related_name="in_perm_activities",
|
||||||
)
|
blank=True,
|
||||||
|
)
|
||||||
|
|
||||||
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 get_herited(self, attrname):
|
def get_herited(self, attrname):
|
||||||
inherited_fields = [f.name for f in
|
try:
|
||||||
ActivityTemplate._meta.get_fields()]
|
tpl_field = ActivityTemplate._meta.get_field(attrname)
|
||||||
m2m_fields = [f.name for f in ActivityTemplate._meta.get_fields()
|
except FieldDoesNotExist:
|
||||||
if f.many_to_many]
|
|
||||||
attr = getattr(self, attrname)
|
|
||||||
if attrname not in inherited_fields:
|
|
||||||
raise FieldError(
|
raise FieldError(
|
||||||
_("%(attrname)s n'est pas un champ héritable"),
|
"%(attrname)s field can't be herited.",
|
||||||
params={'attrname': attrname},
|
params={'attrname': attrname},
|
||||||
)
|
)
|
||||||
elif attrname in m2m_fields:
|
|
||||||
if attr.exists():
|
value = getattr(self, attrname)
|
||||||
return attr
|
|
||||||
|
if tpl_field.many_to_many:
|
||||||
|
if value.exists():
|
||||||
|
return value
|
||||||
else:
|
else:
|
||||||
return getattr(self.parent, attrname)
|
return getattr(self.parent, attrname)
|
||||||
elif attr is None:
|
elif value is None:
|
||||||
return getattr(self.parent, attrname)
|
return getattr(self.parent, attrname)
|
||||||
else:
|
else:
|
||||||
return attr
|
return value
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _("activité")
|
verbose_name = _("activité")
|
||||||
|
|
10
event/validators.py
Normal file
10
event/validators.py
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
from django.core.validators import RegexValidator
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
|
ColorValidator = RegexValidator(
|
||||||
|
regex=r'^#(?:[0-9a-fA-F]{3}){1,2}$',
|
||||||
|
message=_(
|
||||||
|
"La chaîne de caractère rentrée n'est pas une couleur en hexadécimal."
|
||||||
|
),
|
||||||
|
)
|
Loading…
Add table
Add a link
Reference in a new issue