Skip to content

Commit 3949ba5

Browse files
tinylambdaauvipy
authored andcommitted
Implement validate_unique in a more elegant way and solve a validatio… (#179)
* Implement validate_unique in a more elegant way and solve a validation bug in the original implementation * add test case for validate_unique * add test case for validate_unique * add test case for validate_unique * update validate_unique to a more readable implementation * update validate_unique to a more readable implementation * update validate_unique to a more readable implementation * Add tests for validate_unique. Thanks @rsichny
1 parent 639ceb2 commit 3949ba5

File tree

2 files changed

+38
-10
lines changed

2 files changed

+38
-10
lines changed

django_celery_beat/models.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -314,21 +314,24 @@ class Meta:
314314

315315
def validate_unique(self, *args, **kwargs):
316316
super(PeriodicTask, self).validate_unique(*args, **kwargs)
317-
if not self.interval and not self.crontab and not self.solar:
317+
318+
schedule_types = ['interval', 'crontab', 'solar']
319+
selected_schedule_types = [s for s in schedule_types
320+
if getattr(self, s)]
321+
322+
if len(selected_schedule_types) == 0:
318323
raise ValidationError({
319324
'interval': [
320325
'One of interval, crontab, or solar must be set.'
321326
]
322327
})
328+
323329
err_msg = 'Only one of interval, crontab, or solar must be set'
324-
if (self.interval and self.crontab) or (self.crontab and self.solar):
325-
raise ValidationError({
326-
'crontab': [err_msg]
327-
})
328-
if self.interval or self.solar:
329-
raise ValidationError({
330-
'solar': [err_msg]
331-
})
330+
if len(selected_schedule_types) > 1:
331+
error_info = {}
332+
for selected_schedule_type in selected_schedule_types:
333+
error_info[selected_schedule_type] = [err_msg]
334+
raise ValidationError(error_info)
332335

333336
def save(self, *args, **kwargs):
334337
self.exchange = self.exchange or None

t/unit/test_admin.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
from __future__ import absolute_import, unicode_literals
22

3+
from itertools import combinations
34
from django.test import TestCase
45

56
from django_celery_beat.admin import PeriodicTaskAdmin
6-
from django_celery_beat.models import PeriodicTask
7+
from django_celery_beat.models import \
8+
PeriodicTask, \
9+
CrontabSchedule, \
10+
IntervalSchedule, \
11+
SolarSchedule
12+
from django.core.exceptions import ValidationError
713

814

915
class ActionsTests(TestCase):
@@ -51,3 +57,22 @@ def test_toggle_action_all_disabled(self):
5157
self.assertTrue(e1)
5258
self.assertTrue(e2)
5359
self.assertTrue(e3)
60+
61+
def test_validate_unique_raises_if_schedule_not_set(self):
62+
with self.assertRaises(ValidationError):
63+
PeriodicTask().validate_unique()
64+
65+
def test_validate_unique_raises_for_multiple_schedules(self):
66+
schedules = [
67+
('crontab', CrontabSchedule()),
68+
('interval', IntervalSchedule()),
69+
('solar', SolarSchedule()),
70+
]
71+
for options in combinations(schedules, 2):
72+
with self.assertRaises(ValidationError):
73+
PeriodicTask(**dict(options)).validate_unique()
74+
75+
def test_validate_unique_not_raises(self):
76+
PeriodicTask(crontab=CrontabSchedule()).validate_unique()
77+
PeriodicTask(interval=IntervalSchedule()).validate_unique()
78+
PeriodicTask(solar=SolarSchedule()).validate_unique()

0 commit comments

Comments
 (0)