agendas: slug unicity for Agenda, Desk and MeetingType (#34044)
This commit is contained in:
parent
3bf36a1617
commit
fe8f29d4d4
|
@ -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),
|
||||
]
|
|
@ -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')]),
|
||||
),
|
||||
]
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue