Factorize automatic alias creation

This commit is contained in:
Alexandre Iooss 2019-07-24 22:03:07 +02:00
parent f865a6ac7c
commit 32a37eae29
No known key found for this signature in database
GPG Key ID: 6C79278F3FCDCC02
2 changed files with 46 additions and 55 deletions

View File

@ -28,7 +28,7 @@ class NoteAdmin(PolymorphicParentModelAdmin):
list_filter = (PolymorphicChildModelFilter, 'is_active',) list_filter = (PolymorphicChildModelFilter, 'is_active',)
# Use a polymorphic list # Use a polymorphic list
list_display = ('__str__', 'balance', 'is_active') list_display = ('pretty', 'balance', 'is_active')
polymorphic_list = True polymorphic_list = True
# Organize notes by registration date # Organize notes by registration date

View File

@ -3,9 +3,10 @@
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
import unicodedata import unicodedata
from django.conf import settings
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator from django.core.validators import RegexValidator
from django.conf import settings
from django.db import models from django.db import models
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from polymorphic.models import PolymorphicModel from polymorphic.models import PolymorphicModel
@ -46,6 +47,36 @@ class Note(PolymorphicModel):
verbose_name = _("note") verbose_name = _("note")
verbose_name_plural = _("notes") verbose_name_plural = _("notes")
def pretty(self):
"""
:return: Pretty name of this note
"""
return 'Not implemented'
pretty.short_description = _('Note')
def save(self, *args, **kwargs):
"""
Save note with it's alias (called in polymorphic children)
"""
aliases = Alias.objects.filter(name=str(self))
if aliases.exists():
# Alias exists, so check if it is linked to this note
if aliases.first().note != self:
raise ValidationError
# Save note
super().save(*args, **kwargs)
else:
# Alias does not exist yet, so check if it can exist
a = Alias(name=str(self))
a.clean()
# Save note and alias
super().save(*args, **kwargs)
a.note = self
a.save(force_insert=True)
class NoteUser(Note): class NoteUser(Note):
""" """
@ -63,24 +94,10 @@ class NoteUser(Note):
verbose_name_plural = _("users note") verbose_name_plural = _("users note")
def __str__(self): def __str__(self):
return _("%(user)s's note") % {'user': str(self.user)} return str(self.user)
def save(self, *args, **kwargs): def pretty(self):
""" return _("%(user)s's note") % {'user': str(self.user)}
When saving, also create an alias
TODO: remove old alias
"""
created = self.pk is None
try:
alias = Alias.objects.get(normalized_name=Alias.normalize(str(self.user)))
return
except Alias.DoesNotExist:
if created:
super().save(*args, **kwargs)
alias = Alias.objects.create(name=str(self.user), note=self)
alias.save()
if not created:
super().save(*args, **kwargs)
class NoteClub(Note): class NoteClub(Note):
@ -99,24 +116,10 @@ class NoteClub(Note):
verbose_name_plural = _("clubs notes") verbose_name_plural = _("clubs notes")
def __str__(self): def __str__(self):
return _("Note for %(club)s club") % {'club': str(self.club)} return str(self.club)
def save(self, *args, **kwargs): def pretty(self):
""" return _("Note for %(club)s club") % {'club': str(self.club)}
When saving, also create an alias
TODO: remove old alias
"""
created = self.pk is None
try:
alias = Alias.objects.get(normalized_name=Alias.normalize(str(self.club)))
return
except Alias.DoesNotExist:
if created:
super().save(*args, **kwargs)
alias = Alias.objects.create(name=str(self.club), note=self)
alias.save()
if not created:
super().save(*args, **kwargs)
class NoteSpecial(Note): class NoteSpecial(Note):
@ -141,22 +144,8 @@ class NoteSpecial(Note):
def __str__(self): def __str__(self):
return self.special_type return self.special_type
def save(self, *args, **kwargs): def pretty(self):
""" return self.special_type
When saving, also create an alias
TODO: remove old alias
"""
created = self.pk is None
try:
alias = Alias.objects.get(normalized_name=Alias.normalize(self.special_type))
return
except Alias.DoesNotExist:
if created:
super().save(*args, **kwargs)
alias = Alias.objects.create(name=str(self.special_type), note=self)
alias.save()
if not created:
super().save(*args, **kwargs)
class Alias(models.Model): class Alias(models.Model):
@ -200,7 +189,8 @@ class Alias(models.Model):
return ''.join( return ''.join(
char char
for char in unicodedata.normalize('NFKD', string.casefold()) for char in unicodedata.normalize('NFKD', string.casefold())
if all(not unicodedata.category(char).startswith(cat) for cat in {'M', 'P', 'Z', 'C'}) if all(not unicodedata.category(char).startswith(cat)
for cat in {'M', 'P', 'Z', 'C'})
) )
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
@ -208,7 +198,7 @@ class Alias(models.Model):
Handle normalized_name Handle normalized_name
""" """
self.normalized_name = Alias.normalize(self.name) self.normalized_name = Alias.normalize(self.name)
if self.normalized_name < 256: if len(self.normalized_name) < 256:
super().save(*args, **kwargs) super().save(*args, **kwargs)
def clean(self): def clean(self):
@ -217,6 +207,7 @@ class Alias(models.Model):
raise ValidationError(_('Alias too long.')) raise ValidationError(_('Alias too long.'))
try: try:
if self != Alias.objects.get(normalized_name=normalized_name): if self != Alias.objects.get(normalized_name=normalized_name):
raise ValidationError(_('An alias with a similar name already exists.')) raise ValidationError(_('An alias with a similar name '
'already exists.'))
except Alias.DoesNotExist: except Alias.DoesNotExist:
pass pass