Skip to content

Commit 51ba412

Browse files
committed
Changed validation to raise a serialization.ValidationError. Added checks for disallowed characters in tags.
1 parent 70a076c commit 51ba412

File tree

1 file changed

+33
-6
lines changed

1 file changed

+33
-6
lines changed

project/tagging/serializers.py

+33-6
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,60 @@
1+
import regex
12
from rest_framework import serializers
2-
3+
from .models import CustomTag
34

45

56
class TagsSerializerField(serializers.ModelField):
67

78
child = serializers.CharField()
9+
810
default_error_messages = {
9-
'not_a_list': ('Expected a list of tag names but got type "{input_type}".'),
10-
'not_a_string': ('All list items must be type str.')
11+
'not_a_list': ('Expected a list of tag names but got type {input_type}.'),
12+
'not_a_string': ('All tags must be of type str.'),
13+
'emoji or symbol': ('Emoji, pictograps, and symbols are not supported in tags.')
1114
}
1215

16+
class Meta:
17+
model = CustomTag
18+
fields = ('name',)
19+
1320
def __init__(self, **kwargs):
1421
super(TagsSerializerField, self).__init__(**kwargs)
1522

16-
def to_internal_value(self, value):
23+
def validate(self, value):
1724
if not value:
1825
value = []
1926

2027
if not isinstance(value, list):
21-
self.fail('not_a_list', input_type=type(value).__name__)
28+
raise serializers.ValidationError(self.fail('not_a_list', input_type=type(value).__name__))
2229

2330
for tag in value:
2431
if not isinstance(tag, str):
25-
self.fail('not_a_string')
32+
raise serializers.ValidationError(self.fail('not_a_string'))
33+
34+
if self.unsupported_characters(tag):
35+
raise serializers.ValidationError(self.fail('emoji or symbol'))
2636

2737
self.child.run_validation(tag)
2838

2939
return value
3040

41+
def unsupported_characters(self, tag):
42+
'''
43+
Everything NOT a letter, whitespace or combining mark in any unicode language
44+
additionally, miscellaneous mathematical and general symbols are also not allowed.
45+
'''
46+
47+
disallowed_characters = regex.compile(
48+
u"([\p{InMiscellaneous_Mathematical_Symbols-A}"
49+
u"\p{InMiscellaneous_Mathematical_Symbols-B}\p{So}]+)"
50+
u"|([^\p{L}\p{M}\p{Z}\p{N}\p{P}]+)",
51+
regex.VERBOSE)
52+
53+
return True if regex.search(disallowed_characters, tag) else False
54+
55+
def to_internal_value(self, value):
56+
return self.validate(value)
57+
3158
def to_representation(self, instance):
3259

3360
all_fields = instance.tags.all_fields()

0 commit comments

Comments
 (0)