Skip to content

Commit

Permalink
add validator for unique keys
Browse files Browse the repository at this point in the history
  • Loading branch information
jochenklar committed Feb 3, 2017
1 parent b530303 commit 48c398f
Show file tree
Hide file tree
Showing 16 changed files with 125 additions and 8 deletions.
5 changes: 5 additions & 0 deletions apps/conditions/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

from apps.core.utils import get_uri_prefix

from .validators import ConditionUniqueKeyValidator


@python_2_unicode_compatible
class Condition(models.Model):
Expand Down Expand Up @@ -80,6 +82,9 @@ class Meta:
def __str__(self):
return self.uri or self.key

def clean(self):
ConditionUniqueKeyValidator(self).validate()

@property
def source_path(self):
return self.source.path
Expand Down
2 changes: 2 additions & 0 deletions apps/conditions/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from apps.options.models import OptionSet, Option

from .models import Condition
from .validators import ConditionUniqueKeyValidator


class ConditionIndexSerializer(serializers.ModelSerializer):
Expand Down Expand Up @@ -34,6 +35,7 @@ class Meta:
'target_text',
'target_option'
)
validators = (ConditionUniqueKeyValidator(), )


class AttributeOptionSerializer(serializers.ModelSerializer):
Expand Down
7 changes: 7 additions & 0 deletions apps/conditions/validators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from apps.core.validators import UniqueKeyValidator


class ConditionUniqueKeyValidator(UniqueKeyValidator):

app_label = 'conditions'
model_name = 'condition'
57 changes: 55 additions & 2 deletions apps/core/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,59 @@
from django.core.exceptions import ValidationError, ObjectDoesNotExist, MultipleObjectsReturned
from django.utils.translation import ugettext_lazy as _

from rest_framework import serializers

class UniquePathValidator(object):

class UniqueKeyValidator(object):

def __init__(self, instance=None):
self.instance = instance

def set_context(self, serializer):
self.instance = serializer.instance

def validate(self, data=None):
model = apps.get_model(app_label=self.app_label, model_name=self.model_name)

if data:
key = data['key']
else:
key = self.instance.key

try:
if self.instance:
model.objects.exclude(pk=self.instance.pk).get(key=key)
else:
model.objects.get(key=key)
except ObjectDoesNotExist:
return
except MultipleObjectsReturned:
pass

raise ValidationError({
'key': _('%(model)s with this key already exists.') % {
'model': model._meta.verbose_name.title()
}
})

def __call__(self, data=None):
try:
self.validate(data)
except ValidationError as e:
raise serializers.ValidationError({
'key': e.error_dict['key'][0][0]
})


class UniquePathValidator(object):

def __init__(self, instance=None):
self.instance = instance

def set_context(self, serializer):
self.instance = serializer.instance

def validate(self, data=None):
model = apps.get_model(app_label=self.app_label, model_name=self.model_name)

if data:
Expand All @@ -29,7 +72,17 @@ def __call__(self, data=None):
except MultipleObjectsReturned:
pass

raise ValidationError(_('Another %(model)s with the path "%(path)s" already exists. Please adjust the the Key.') % {
raise ValidationError({
'key': _('%(model)s with the path "%(path)s" already exists. Please adjust the the Key.') % {
'model': model._meta.verbose_name.title(),
'path': path
}
})

def __call__(self, data=None):
try:
self.validate(data)
except ValidationError as e:
raise serializers.ValidationError({
'key': e.error_dict['key'][0][0]
})
5 changes: 4 additions & 1 deletion apps/options/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from apps.core.models import TranslationMixin
from apps.conditions.models import Condition

from .validators import OptionUniquePathValidator
from .validators import OptionSetUniqueKeyValidator, OptionUniquePathValidator


@python_2_unicode_compatible
Expand Down Expand Up @@ -60,6 +60,9 @@ def save(self, *args, **kwargs):
for option in self.options.all():
option.save()

def clean(self):
OptionSetUniqueKeyValidator(self).validate()

@property
def label(self):
return self.key
Expand Down
3 changes: 2 additions & 1 deletion apps/options/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from apps.conditions.models import Condition

from .models import OptionSet, Option
from .validators import OptionUniquePathValidator
from .validators import OptionSetUniqueKeyValidator, OptionUniquePathValidator


class OptionSetIndexOptionsSerializer(serializers.ModelSerializer):
Expand Down Expand Up @@ -42,6 +42,7 @@ class Meta:
'order',
'conditions'
)
validators = (OptionSetUniqueKeyValidator(),)


class OptionSerializer(serializers.ModelSerializer):
Expand Down
8 changes: 7 additions & 1 deletion apps/options/validators.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
from apps.core.validators import UniquePathValidator
from apps.core.validators import UniqueKeyValidator, UniquePathValidator


class OptionSetUniqueKeyValidator(UniqueKeyValidator):

app_label = 'options'
model_name = 'optionset'


class OptionUniquePathValidator(UniquePathValidator):
Expand Down
4 changes: 4 additions & 0 deletions apps/questions/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from .managers import QuestionEntityManager
from .validators import (
CatalogUniqueKeyValidator,
SectionUniquePathValidator,
SubsectionUniquePathValidator,
QuestionEntityUniquePathValidator,
Expand Down Expand Up @@ -71,6 +72,9 @@ def save(self, *args, **kwargs):
for section in self.sections.all():
section.save()

def clean(self):
CatalogUniqueKeyValidator(self)()

@property
def title(self):
return self.trans('title')
Expand Down
2 changes: 2 additions & 0 deletions apps/questions/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from .models import Catalog, Section, Subsection, QuestionEntity, Question
from .validators import (
CatalogUniqueKeyValidator,
SectionUniquePathValidator,
SubsectionUniquePathValidator,
QuestionEntityUniquePathValidator,
Expand Down Expand Up @@ -40,6 +41,7 @@ class Meta:
'title_de',
'title'
)
validators = (CatalogUniqueKeyValidator(), )


class SectionIndexSerializer(serializers.ModelSerializer):
Expand Down
8 changes: 7 additions & 1 deletion apps/questions/validators.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
from apps.core.validators import UniquePathValidator
from apps.core.validators import UniqueKeyValidator, UniquePathValidator


class CatalogUniqueKeyValidator(UniqueKeyValidator):

app_label = 'questions'
model_name = 'catalog'


class SectionUniquePathValidator(UniquePathValidator):
Expand Down
5 changes: 5 additions & 0 deletions apps/tasks/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
from apps.domain.models import Attribute
from apps.conditions.models import Condition

from .validators import TaskUniqueKeyValidator


@python_2_unicode_compatible
class Task(TranslationMixin, models.Model):
Expand Down Expand Up @@ -82,6 +84,9 @@ def save(self, *args, **kwargs):
self.uri = self.build_uri()
super(Task, self).save(*args, **kwargs)

def clean(self):
TaskUniqueKeyValidator(self).validate()

@property
def title(self):
return self.trans('title')
Expand Down
6 changes: 4 additions & 2 deletions apps/tasks/serializers.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from rest_framework import serializers

from .models import Task

from apps.domain.models import Attribute
from apps.conditions.models import Condition

from .models import Task
from .validators import TaskUniqueKeyValidator


class TaskIndexSerializer(serializers.ModelSerializer):

Expand Down Expand Up @@ -35,6 +36,7 @@ class Meta:
'text_de',
'conditions'
)
validators = (TaskUniqueKeyValidator(), )


class AttributeSerializer(serializers.ModelSerializer):
Expand Down
7 changes: 7 additions & 0 deletions apps/tasks/validators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from apps.core.validators import UniqueKeyValidator


class TaskUniqueKeyValidator(UniqueKeyValidator):

app_label = 'tasks'
model_name = 'task'
5 changes: 5 additions & 0 deletions apps/views/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
from apps.domain.models import AttributeEntity
from apps.conditions.models import Condition

from .validators import ViewUniqueKeyValidator


@python_2_unicode_compatible
class View(models.Model, TranslationMixin):
Expand Down Expand Up @@ -73,6 +75,9 @@ def save(self, *args, **kwargs):
self.uri = self.build_uri()
super(View, self).save(*args, **kwargs)

def clean(self):
ViewUniqueKeyValidator(self).validate()

@property
def title(self):
return self.trans('title')
Expand Down
2 changes: 2 additions & 0 deletions apps/views/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from rest_framework import exceptions

from .models import View
from .validators import ViewUniqueKeyValidator


class ViewIndexSerializer(serializers.ModelSerializer):
Expand Down Expand Up @@ -43,6 +44,7 @@ class Meta:
'help_de',
'template'
)
validators = (ViewUniqueKeyValidator(), )


class ExportSerializer(serializers.ModelSerializer):
Expand Down
7 changes: 7 additions & 0 deletions apps/views/validators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from apps.core.validators import UniqueKeyValidator


class ViewUniqueKeyValidator(UniqueKeyValidator):

app_label = 'views'
model_name = 'view'

0 comments on commit 48c398f

Please sign in to comment.