diff --git a/apps/location/migrations/0007_auto_20190826_1342.py b/apps/location/migrations/0007_auto_20190826_1342.py new file mode 100644 index 00000000..7a6c5fe6 --- /dev/null +++ b/apps/location/migrations/0007_auto_20190826_1342.py @@ -0,0 +1,24 @@ +# Generated by Django 2.2.4 on 2019-08-26 13:42 + +from django.db import migrations, models +import utils.methods +import utils.validators + + +class Migration(migrations.Migration): + + dependencies = [ + ('location', '0006_country_image'), + ] + + operations = [ + migrations.RemoveField( + model_name='country', + name='image', + ), + migrations.AddField( + model_name='country', + name='svg_image', + field=models.FileField(blank=True, default=None, null=True, upload_to=utils.methods.svg_image_path, validators=[utils.validators.svg_image_validator], verbose_name='SVG image'), + ), + ] diff --git a/apps/location/models.py b/apps/location/models.py index 5b4d262c..f69eeeb9 100644 --- a/apps/location/models.py +++ b/apps/location/models.py @@ -3,14 +3,14 @@ from django.contrib.gis.db import models from django.contrib.postgres.fields import JSONField from django.utils.translation import gettext_lazy as _ -from utils.models import ProjectBaseMixin, LocaleManagerMixin, ImageMixin +from utils.models import ProjectBaseMixin, LocaleManagerMixin, SVGImageMixin class CountryManager(LocaleManagerMixin): """Extended manager for Country model.""" -class Country(ImageMixin, ProjectBaseMixin): +class Country(SVGImageMixin, ProjectBaseMixin): """Country model.""" name = JSONField(null=True, blank=True, default=None, diff --git a/apps/location/serializers.py b/apps/location/serializers.py index bfce3c05..89c87245 100644 --- a/apps/location/serializers.py +++ b/apps/location/serializers.py @@ -14,7 +14,7 @@ class CountrySerializer(serializers.ModelSerializer): fields = [ 'id', 'code', - 'image', + 'svg_image', 'name_trans', ] diff --git a/apps/utils/methods.py b/apps/utils/methods.py index e0f9325a..a26c306c 100644 --- a/apps/utils/methods.py +++ b/apps/utils/methods.py @@ -1,6 +1,7 @@ """Utils app method.""" import random import re + from django.conf import settings from django.http.request import HttpRequest from django.utils.timezone import datetime @@ -40,3 +41,12 @@ def image_path(instance, filename): instance._meta.model_name, datetime.now().strftime(settings.REST_DATE_FORMAT), filename) + + +def svg_image_path(instance, filename): + """Determine SVG path method.""" + filename = '%s.svg' % generate_code() + return 'image/svg/%s/%s/%s' % ( + instance._meta.model_name, + datetime.now().strftime(settings.REST_DATE_FORMAT), + filename) diff --git a/apps/utils/models.py b/apps/utils/models.py index d3562d6e..9498982c 100644 --- a/apps/utils/models.py +++ b/apps/utils/models.py @@ -9,7 +9,8 @@ from django.utils.html import mark_safe from django.utils.translation import ugettext_lazy as _ from easy_thumbnails.fields import ThumbnailerImageField -from utils.methods import image_path +from utils.methods import image_path, svg_image_path +from utils.validators import svg_image_validator class ProjectBaseMixin(models.Model): @@ -86,6 +87,18 @@ class ImageMixin(models.Model): image_tag.allow_tags = True +class SVGImageMixin(models.Model): + """SVG image model.""" + + svg_image = models.FileField(upload_to=svg_image_path, + blank=True, null=True, default=None, + validators=[svg_image_validator, ], + verbose_name=_('SVG image')) + + class Meta: + abstract = True + + class PlatformMixin(models.Model): """Platforms""" diff --git a/apps/utils/validators.py b/apps/utils/validators.py new file mode 100644 index 00000000..2808db9b --- /dev/null +++ b/apps/utils/validators.py @@ -0,0 +1,22 @@ +"""DB field validators""" +import xml.etree.cElementTree as et + +from django.core.exceptions import ValidationError + + +def svg_image_validator(file: object) -> object: + """Validate SVG file""" + tag = None + try: + for event, el in et.iterparse(file, ('start',)): + tag = el.tag + break + assert tag == '{http://www.w3.org/2000/svg}svg' + except: + raise ValidationError( + message='Invalid SVG image file', + code='invalid_svg_image', + params={'value': file}, + ) + else: + return file diff --git a/project/urls/__init__.py b/project/urls/__init__.py index 3f1ee7a2..ef909dcf 100644 --- a/project/urls/__init__.py +++ b/project/urls/__init__.py @@ -74,4 +74,5 @@ urlpatterns = urlpatterns + \ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) if settings.DEBUG: + urlpatterns.extend(urlpatterns_doc)