Projet

Général

Profil

0001-agendas-slug-unicity-for-Agenda-Desk-and-MeetingType.patch

Lauréline Guérin, 07 novembre 2019 17:00

Télécharger (9,08 ko)

Voir les différences:

Subject: [PATCH] agendas: slug unicity for Agenda, Desk and MeetingType
 (#34044)

 .../migrations/0030_auto_20191107_1200.py     | 58 ++++++++++++++
 .../migrations/0031_auto_20191107_1225.py     | 28 +++++++
 chrono/agendas/models.py                      | 78 ++++++++-----------
 3 files changed, 119 insertions(+), 45 deletions(-)
 create mode 100644 chrono/agendas/migrations/0030_auto_20191107_1200.py
 create mode 100644 chrono/agendas/migrations/0031_auto_20191107_1225.py
chrono/agendas/migrations/0030_auto_20191107_1200.py
1
# -*- coding: utf-8 -*-
2
from __future__ import unicode_literals
3

  
4
from django.db import migrations
5
from django.utils.text import slugify
6

  
7

  
8
def generate_slug(instance, **query_filters):
9
    base_slug = slugify(instance.label)
10
    slug = base_slug
11
    i = 1
12
    while True:
13
        queryset = instance._meta.model.objects.filter(slug=slug, **query_filters).exclude(pk=instance.pk)
14
        if not queryset.exists():
15
            break
16
        slug = '%s-%s' % (base_slug, i)
17
        i += 1
18
    return slug
19

  
20

  
21
def set_slug_on_agendas(apps, schema_editor):
22
    Agenda = apps.get_model('agendas', 'Agenda')
23
    for agenda in Agenda.objects.all().order_by('-pk'):
24
        if not Agenda.objects.filter(slug=agenda.slug).exclude(pk=agenda.pk).exists():
25
            continue
26
        agenda.slug = generate_slug(agenda)
27
        agenda.save(update_fields=['slug'])
28

  
29

  
30
def set_slug_on_desks(apps, schema_editor):
31
    Desk = apps.get_model('agendas', 'Desk')
32
    for desk in Desk.objects.all().order_by('-pk'):
33
        if not Desk.objects.filter(slug=desk.slug, agenda=desk.agenda).exclude(pk=desk.pk).exists():
34
            continue
35
        desk.slug = generate_slug(desk, agenda=desk.agenda)
36
        desk.save(update_fields=['slug'])
37

  
38

  
39
def set_slug_on_meetingtypes(apps, schema_editor):
40
    MeetingType = apps.get_model('agendas', 'MeetingType')
41
    for meetingtype in MeetingType.objects.all().order_by('-pk'):
42
        if not MeetingType.objects.filter(slug=meetingtype.slug, agenda=meetingtype.agenda).exclude(pk=meetingtype.pk).exists():
43
            continue
44
        meetingtype.slug = generate_slug(meetingtype, agenda=meetingtype.agenda)
45
        meetingtype.save(update_fields=['slug'])
46

  
47

  
48
class Migration(migrations.Migration):
49

  
50
    dependencies = [
51
        ('agendas', '0029_auto_20191106_1320'),
52
    ]
53

  
54
    operations = [
55
        migrations.RunPython(set_slug_on_agendas, lambda x, y: None),
56
        migrations.RunPython(set_slug_on_desks, lambda x, y: None),
57
        migrations.RunPython(set_slug_on_meetingtypes, lambda x, y: None),
58
    ]
chrono/agendas/migrations/0031_auto_20191107_1225.py
1
# -*- coding: utf-8 -*-
2
# Generated by Django 1.11.18 on 2019-11-07 11:25
3
from __future__ import unicode_literals
4

  
5
from django.db import migrations, models
6

  
7

  
8
class Migration(migrations.Migration):
9

  
10
    dependencies = [
11
        ('agendas', '0030_auto_20191107_1200'),
12
    ]
13

  
14
    operations = [
15
        migrations.AlterField(
16
            model_name='agenda',
17
            name='slug',
18
            field=models.SlugField(max_length=160, unique=True, verbose_name='Identifier'),
19
        ),
20
        migrations.AlterUniqueTogether(
21
            name='desk',
22
            unique_together=set([('agenda', 'slug')]),
23
        ),
24
        migrations.AlterUniqueTogether(
25
            name='meetingtype',
26
            unique_together=set([('agenda', 'slug')]),
27
        ),
28
    ]
chrono/agendas/models.py
49 49
    return dtime.hour == 0 and dtime.minute == 0
50 50

  
51 51

  
52
def generate_slug(instance, **query_filters):
53
    base_slug = slugify(instance.label)
54
    slug = base_slug
55
    i = 1
56
    while True:
57
        if not instance._meta.model.objects.filter(slug=slug, **query_filters).exists():
58
            break
59
        slug = '%s-%s' % (base_slug, i)
60
        i += 1
61
    return slug
62

  
63

  
52 64
class ICSError(Exception):
53 65
    pass
54 66

  
......
59 71

  
60 72
class Agenda(models.Model):
61 73
    label = models.CharField(_('Label'), max_length=150)
62
    slug = models.SlugField(_('Identifier'), max_length=160)
74
    slug = models.SlugField(_('Identifier'), max_length=160, unique=True)
63 75
    kind = models.CharField(_('Kind'), max_length=20, choices=AGENDA_KINDS, default='events')
64 76
    minimal_booking_delay = models.PositiveIntegerField(
65 77
            _('Minimal booking delay (in days)'), default=1)
......
77 89

  
78 90
    def save(self, *args, **kwargs):
79 91
        if not self.slug:
80
            base_slug = slugify(self.label)
81
            slug = base_slug
82
            i = 1
83
            while True:
84
                try:
85
                    Agenda.objects.get(slug=slug)
86
                except self.DoesNotExist:
87
                    break
88
                slug = '%s-%s' % (base_slug, i)
89
                i += 1
90
            self.slug = slug
92
            self.slug = generate_slug(self)
91 93
        super(Agenda, self).save(*args, **kwargs)
92 94

  
93 95
    def get_absolute_url(self):
......
149 151
                except Group.DoesNotExist:
150 152
                    raise AgendaImportError(_('Missing "%s" role') % permissions[permission])
151 153
        agenda, created = cls.objects.get_or_create(slug=data['slug'], defaults=data)
154
        if not created:
155
            for k, v in data.items():
156
                setattr(agenda, k, v)
152 157
        if data['kind'] == 'events':
153 158
            if overwrite:
154 159
                Event.objects.filter(agenda=agenda).delete()
......
252 257

  
253 258
    class Meta:
254 259
        ordering = ['duration', 'label']
260
        unique_together = ['agenda', 'slug']
255 261

  
256 262
    def save(self, *args, **kwargs):
257 263
        if not self.slug:
258
            base_slug = slugify(self.label)
259
            slug = base_slug
260
            i = 1
261
            while True:
262
                try:
263
                    MeetingType.objects.get(slug=slug, agenda=self.agenda)
264
                except self.DoesNotExist:
265
                    break
266
                slug = '%s-%s' % (base_slug, i)
267
                i += 1
268
            self.slug = slug
264
            self.slug = generate_slug(self, agenda=self.agenda)
269 265
        super(MeetingType, self).save(*args, **kwargs)
270 266

  
271 267
    @classmethod
272 268
    def import_json(cls, data):
273
        return cls(**data)
269
        meeting_type, created = cls.objects.get_or_create(
270
            slug=data['slug'], agenda=data['agenda'], defaults=data)
271
        if not created:
272
            for k, v in data.items():
273
                setattr(meeting_type, k, v)
274
        return meeting_type
274 275

  
275 276
    def export_json(self):
276 277
        return {
......
307 308
    def save(self, *args, **kwargs):
308 309
        self.check_full()
309 310
        if not self.slug:
310
            base_slug = slugify(self.label)
311
            slug = base_slug
312
            i = 1
313
            while True:
314
                if not Event.objects.filter(slug=slug).exists():
315
                    break
316
                slug = '%s-%s' % (base_slug, i)
317
                i += 1
318
            self.slug = slug
311
            self.slug = generate_slug(self)
319 312
        return super(Event, self).save(*args, **kwargs)
320 313

  
321 314
    def check_full(self):
......
447 440

  
448 441
    class Meta:
449 442
        ordering = ['label']
443
        unique_together = ['agenda', 'slug']
450 444

  
451 445
    def save(self, *args, **kwargs):
452 446
        if not self.slug:
453
            base_slug = slugify(self.label)
454
            slug = base_slug
455
            i = 1
456
            while True:
457
                try:
458
                    Desk.objects.get(slug=slug, agenda=self.agenda)
459
                except self.DoesNotExist:
460
                    break
461
                slug = '%s-%s' % (base_slug, i)
462
                i += 1
463
            self.slug = slug
447
            self.slug = generate_slug(self, agenda=self.agenda)
464 448
        super(Desk, self).save(*args, **kwargs)
465 449

  
466 450
    @classmethod
467 451
    def import_json(cls, data):
468 452
        timeperiods = data.pop('timeperiods')
469 453
        exceptions = data.pop('exceptions')
470
        instance, created = cls.objects.get_or_create(**data)
454
        instance, created = cls.objects.get_or_create(
455
            slug=data['slug'], agenda=data['agenda'], defaults=data)
456
        if not created:
457
            for k, v in data.items():
458
                setattr(instance, k, v)
471 459
        for timeperiod in timeperiods:
472 460
            timeperiod['desk'] = instance
473 461
            TimePeriod.import_json(timeperiod).save()
474
-