django-orchestra/orchestra/contrib/websites/serializers.py

131 lines
4.7 KiB
Python
Raw Normal View History

from django.core.exceptions import ValidationError
2014-05-08 16:59:35 +00:00
from rest_framework import serializers
2015-05-18 15:21:42 +00:00
from orchestra.api.serializers import HyperlinkedModelSerializer, RelatedHyperlinkedModelSerializer
2015-04-05 10:46:24 +00:00
from orchestra.contrib.accounts.serializers import AccountSerializerMixin
2014-05-08 16:59:35 +00:00
2015-05-18 15:21:42 +00:00
from .directives import SiteDirective
2015-04-23 14:34:04 +00:00
from .models import Website, Content, WebsiteDirective
2015-05-19 13:27:04 +00:00
from .utils import normurlpath
2015-03-10 22:27:32 +00:00
from .validators import validate_domain_protocol
2014-05-08 16:59:35 +00:00
2015-05-18 15:21:42 +00:00
class RelatedDomainSerializer(AccountSerializerMixin, RelatedHyperlinkedModelSerializer):
class Meta:
model = Website.domains.field.related_model
2015-04-30 09:51:55 +00:00
fields = ('url', 'id', 'name')
2015-05-18 15:21:42 +00:00
class RelatedWebAppSerializer(AccountSerializerMixin, RelatedHyperlinkedModelSerializer):
class Meta:
model = Content.webapp.field.related_model
2015-04-30 09:51:55 +00:00
fields = ('url', 'id', 'name', 'type')
2015-05-18 15:21:42 +00:00
class ContentSerializer(serializers.ModelSerializer):
webapp = RelatedWebAppSerializer()
2014-05-08 16:59:35 +00:00
class Meta:
model = Content
fields = ('webapp', 'path')
def get_identity(self, data):
return '%s-%s' % (data.get('website'), data.get('path'))
2014-05-08 16:59:35 +00:00
2015-04-23 14:34:04 +00:00
class DirectiveSerializer(serializers.ModelSerializer):
class Meta:
model = WebsiteDirective
fields = ('name', 'value')
2015-04-23 14:34:04 +00:00
def to_representation(self, instance):
return {prop.name: prop.value for prop in instance.all()}
2015-04-23 14:34:04 +00:00
def to_internal_value(self, data):
return data
2014-10-15 21:18:50 +00:00
class WebsiteSerializer(AccountSerializerMixin, HyperlinkedModelSerializer):
2015-05-18 15:21:42 +00:00
domains = RelatedDomainSerializer(many=True, required=False)
contents = ContentSerializer(required=False, many=True, source='content_set')
2015-04-23 14:34:04 +00:00
directives = DirectiveSerializer(required=False)
2014-05-08 16:59:35 +00:00
class Meta:
model = Website
2015-04-30 09:51:55 +00:00
fields = ('url', 'id', 'name', 'protocol', 'domains', 'is_active', 'contents', 'directives')
2016-02-11 14:24:09 +00:00
postonly_fields = ('name',)
2015-05-18 15:21:42 +00:00
def validate(self, data):
2015-03-23 15:36:51 +00:00
""" Prevent multiples domains on the same protocol """
2015-05-18 15:21:42 +00:00
# Validate location and directive uniqueness
errors = []
directives = data.get('directives', [])
if directives:
locations = set()
for content in data.get('content_set', []):
location = content.get('path')
if location is not None:
2015-05-19 13:27:04 +00:00
locations.add(normurlpath(location))
2015-05-18 15:21:42 +00:00
values = defaultdict(list)
for name, value in directives.items():
directive = {
'name': name,
'value': value,
}
try:
SiteDirective.get(name).validate_uniqueness(directive, values, locations)
except ValidationError as err:
errors.append(err)
# Validate domain protocol uniqueness
instance = self.instance
for domain in data['domains']:
2015-03-10 22:27:32 +00:00
try:
2015-05-18 15:21:42 +00:00
validate_domain_protocol(instance, domain, data['protocol'])
except ValidationError as err:
errors.append(err)
if errors:
raise ValidationError(errors)
return data
2015-04-23 14:34:04 +00:00
def create(self, validated_data):
2015-04-24 14:03:42 +00:00
directives_data = validated_data.pop('directives')
2015-04-23 14:34:04 +00:00
webapp = super(WebsiteSerializer, self).create(validated_data)
2015-04-24 14:03:42 +00:00
for key, value in directives_data.items():
WebsiteDirective.objects.create(webapp=webapp, name=key, value=value)
2015-04-23 14:34:04 +00:00
return webap
2015-05-18 15:21:42 +00:00
def update_directives(self, instance, directives_data):
2015-04-23 14:34:04 +00:00
existing = {}
2015-04-24 14:03:42 +00:00
for obj in instance.directives.all():
2015-04-23 14:34:04 +00:00
existing[obj.name] = obj
posted = set()
2015-04-24 14:03:42 +00:00
for key, value in directives_data.items():
2015-04-23 14:34:04 +00:00
posted.add(key)
try:
2015-04-24 14:03:42 +00:00
directive = existing[key]
2015-04-23 14:34:04 +00:00
except KeyError:
2015-04-24 14:03:42 +00:00
directive = instance.directives.create(name=key, value=value)
2015-04-23 14:34:04 +00:00
else:
2015-04-24 14:03:42 +00:00
if directive.value != value:
directive.value = value
directive.save(update_fields=('value',))
2015-04-23 14:34:04 +00:00
for to_delete in set(existing.keys())-posted:
existing[to_delete].delete()
2015-05-18 15:21:42 +00:00
def update_contents(self, instance, contents_data):
raise NotImplementedError
2015-05-18 15:21:42 +00:00
def update_domains(self, instance, domains_data):
raise NotImplementedError
2015-05-18 15:21:42 +00:00
def update(self, instance, validated_data):
directives_data = validated_data.pop('directives')
domains_data = validated_data.pop('domains')
contents_data = validated_data.pop('content_set')
instance = super(WebsiteSerializer, self).update(instance, validated_data)
self.update_directives(instance, directives_data)
self.update_contents(instance, contents_data)
self.update_domains(instance, domains_data)
2015-04-23 14:34:04 +00:00
return instance