agendas: slug unicity for Agenda, Desk and MeetingType (#34044)

This commit is contained in:
Lauréline Guérin 2019-11-07 12:27:05 +01:00
parent 3bf36a1617
commit fe8f29d4d4
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
3 changed files with 117 additions and 45 deletions

View File

@ -0,0 +1,58 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations
from django.utils.text import slugify
def generate_slug(instance, **query_filters):
base_slug = slugify(instance.label)
slug = base_slug
i = 1
while True:
queryset = instance._meta.model.objects.filter(slug=slug, **query_filters).exclude(pk=instance.pk)
if not queryset.exists():
break
slug = '%s-%s' % (base_slug, i)
i += 1
return slug
def set_slug_on_agendas(apps, schema_editor):
Agenda = apps.get_model('agendas', 'Agenda')
for agenda in Agenda.objects.all().order_by('-pk'):
if not Agenda.objects.filter(slug=agenda.slug).exclude(pk=agenda.pk).exists():
continue
agenda.slug = generate_slug(agenda)
agenda.save(update_fields=['slug'])
def set_slug_on_desks(apps, schema_editor):
Desk = apps.get_model('agendas', 'Desk')
for desk in Desk.objects.all().order_by('-pk'):
if not Desk.objects.filter(slug=desk.slug, agenda=desk.agenda).exclude(pk=desk.pk).exists():
continue
desk.slug = generate_slug(desk, agenda=desk.agenda)
desk.save(update_fields=['slug'])
def set_slug_on_meetingtypes(apps, schema_editor):
MeetingType = apps.get_model('agendas', 'MeetingType')
for meetingtype in MeetingType.objects.all().order_by('-pk'):
if not MeetingType.objects.filter(slug=meetingtype.slug, agenda=meetingtype.agenda).exclude(pk=meetingtype.pk).exists():
continue
meetingtype.slug = generate_slug(meetingtype, agenda=meetingtype.agenda)
meetingtype.save(update_fields=['slug'])
class Migration(migrations.Migration):
dependencies = [
('agendas', '0029_auto_20191106_1320'),
]
operations = [
migrations.RunPython(set_slug_on_agendas, lambda x, y: None),
migrations.RunPython(set_slug_on_desks, lambda x, y: None),
migrations.RunPython(set_slug_on_meetingtypes, lambda x, y: None),
]

View File

@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.18 on 2019-11-07 11:25
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('agendas', '0030_auto_20191107_1200'),
]
operations = [
migrations.AlterField(
model_name='agenda',
name='slug',
field=models.SlugField(max_length=160, unique=True, verbose_name='Identifier'),
),
migrations.AlterUniqueTogether(
name='desk',
unique_together=set([('agenda', 'slug')]),
),
migrations.AlterUniqueTogether(
name='meetingtype',
unique_together=set([('agenda', 'slug')]),
),
]

View File

@ -49,6 +49,16 @@ def is_midnight(dtime):
return dtime.hour == 0 and dtime.minute == 0
def generate_slug(instance, **query_filters):
base_slug = slugify(instance.label)
slug = base_slug
i = 1
while instance._meta.model.objects.filter(slug=slug, **query_filters).exists():
slug = '%s-%s' % (base_slug, i)
i += 1
return slug
class ICSError(Exception):
pass
@ -59,7 +69,7 @@ class AgendaImportError(Exception):
class Agenda(models.Model):
label = models.CharField(_('Label'), max_length=150)
slug = models.SlugField(_('Identifier'), max_length=160)
slug = models.SlugField(_('Identifier'), max_length=160, unique=True)
kind = models.CharField(_('Kind'), max_length=20, choices=AGENDA_KINDS, default='events')
minimal_booking_delay = models.PositiveIntegerField(
_('Minimal booking delay (in days)'), default=1)
@ -77,17 +87,7 @@ class Agenda(models.Model):
def save(self, *args, **kwargs):
if not self.slug:
base_slug = slugify(self.label)
slug = base_slug
i = 1
while True:
try:
Agenda.objects.get(slug=slug)
except self.DoesNotExist:
break
slug = '%s-%s' % (base_slug, i)
i += 1
self.slug = slug
self.slug = generate_slug(self)
super(Agenda, self).save(*args, **kwargs)
def get_absolute_url(self):
@ -149,6 +149,9 @@ class Agenda(models.Model):
except Group.DoesNotExist:
raise AgendaImportError(_('Missing "%s" role') % permissions[permission])
agenda, created = cls.objects.get_or_create(slug=data['slug'], defaults=data)
if not created:
for k, v in data.items():
setattr(agenda, k, v)
if data['kind'] == 'events':
if overwrite:
Event.objects.filter(agenda=agenda).delete()
@ -252,25 +255,21 @@ class MeetingType(models.Model):
class Meta:
ordering = ['duration', 'label']
unique_together = ['agenda', 'slug']
def save(self, *args, **kwargs):
if not self.slug:
base_slug = slugify(self.label)
slug = base_slug
i = 1
while True:
try:
MeetingType.objects.get(slug=slug, agenda=self.agenda)
except self.DoesNotExist:
break
slug = '%s-%s' % (base_slug, i)
i += 1
self.slug = slug
self.slug = generate_slug(self, agenda=self.agenda)
super(MeetingType, self).save(*args, **kwargs)
@classmethod
def import_json(cls, data):
return cls(**data)
meeting_type, created = cls.objects.get_or_create(
slug=data['slug'], agenda=data['agenda'], defaults=data)
if not created:
for k, v in data.items():
setattr(meeting_type, k, v)
return meeting_type
def export_json(self):
return {
@ -307,15 +306,7 @@ class Event(models.Model):
def save(self, *args, **kwargs):
self.check_full()
if not self.slug:
base_slug = slugify(self.label)
slug = base_slug
i = 1
while True:
if not Event.objects.filter(slug=slug).exists():
break
slug = '%s-%s' % (base_slug, i)
i += 1
self.slug = slug
self.slug = generate_slug(self)
return super(Event, self).save(*args, **kwargs)
def check_full(self):
@ -447,27 +438,22 @@ class Desk(models.Model):
class Meta:
ordering = ['label']
unique_together = ['agenda', 'slug']
def save(self, *args, **kwargs):
if not self.slug:
base_slug = slugify(self.label)
slug = base_slug
i = 1
while True:
try:
Desk.objects.get(slug=slug, agenda=self.agenda)
except self.DoesNotExist:
break
slug = '%s-%s' % (base_slug, i)
i += 1
self.slug = slug
self.slug = generate_slug(self, agenda=self.agenda)
super(Desk, self).save(*args, **kwargs)
@classmethod
def import_json(cls, data):
timeperiods = data.pop('timeperiods')
exceptions = data.pop('exceptions')
instance, created = cls.objects.get_or_create(**data)
instance, created = cls.objects.get_or_create(
slug=data['slug'], agenda=data['agenda'], defaults=data)
if not created:
for k, v in data.items():
setattr(instance, k, v)
for timeperiod in timeperiods:
timeperiod['desk'] = instance
TimePeriod.import_json(timeperiod).save()