serializers.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. from rest_framework import serializers
  2. from rest_framework.exceptions import ValidationError
  3. from desecapi.models import Domain, Donation, User, RR, RRset
  4. from djoser import serializers as djoserSerializers
  5. from django.db import transaction
  6. class RRSerializer(serializers.ModelSerializer):
  7. class Meta:
  8. model = RR
  9. fields = ('content',)
  10. class RRsetSerializer(serializers.ModelSerializer):
  11. domain = serializers.StringRelatedField()
  12. subname = serializers.CharField(allow_blank=True, required=False)
  13. type = serializers.CharField(required=False)
  14. records = serializers.SerializerMethodField()
  15. class Meta:
  16. model = RRset
  17. fields = ('domain', 'subname', 'name', 'records', 'ttl', 'type',)
  18. def _set_records(self, instance):
  19. # Although serializer fields have required=True by default, that
  20. # setting does not work for the SerializerMethodField "records".
  21. # Thus, let's wrap our read access to include the validation check.
  22. records = self.context['request'].data.get('records')
  23. if records is None:
  24. raise ValidationError({'records': 'This field is required.'},
  25. code='required')
  26. records_data = [{'content': x} for x in records]
  27. rr_serializer = RRSerializer(data=records_data, many=True,
  28. allow_empty=False)
  29. if not rr_serializer.is_valid():
  30. errors = rr_serializer.errors
  31. if 'non_field_errors' in errors:
  32. errors['records'] = errors.pop('non_field_errors')
  33. raise serializers.ValidationError(errors)
  34. instance.set_rrs([x['content'] for x in rr_serializer.validated_data])
  35. @transaction.atomic
  36. def create(self, validated_data):
  37. instance = super().create(validated_data)
  38. self._set_records(instance)
  39. return instance
  40. @transaction.atomic
  41. def update(self, instance, validated_data):
  42. instance = super().update(instance, validated_data)
  43. # Update records only if required (PUT) or provided (PATCH)
  44. if not self.partial or 'records' in self.context['request'].data:
  45. instance.records.all().delete()
  46. self._set_records(instance)
  47. return instance
  48. def get_records(self, obj):
  49. return list(obj.records.values_list('content', flat=True))
  50. def validate_type(self, value):
  51. if value in RRset.RESTRICTED_TYPES:
  52. raise serializers.ValidationError(
  53. "You cannot tinker with the %s RRset." % value)
  54. return value
  55. class DomainSerializer(serializers.ModelSerializer):
  56. owner = serializers.ReadOnlyField(source='owner.email')
  57. name = serializers.RegexField(regex=r'^[A-Za-z0-9_.-]+$', trim_whitespace=False)
  58. class Meta:
  59. model = Domain
  60. fields = ('name', 'owner', 'keys')
  61. class DonationSerializer(serializers.ModelSerializer):
  62. class Meta:
  63. model = Donation
  64. fields = ('name', 'iban', 'bic', 'amount', 'message', 'email')
  65. class UserSerializer(djoserSerializers.UserSerializer):
  66. class Meta(djoserSerializers.UserSerializer.Meta):
  67. fields = tuple(User.REQUIRED_FIELDS) + (
  68. User.USERNAME_FIELD,
  69. )
  70. class UserCreateSerializer(djoserSerializers.UserCreateSerializer):
  71. class Meta(djoserSerializers.UserCreateSerializer.Meta):
  72. fields = tuple(User.REQUIRED_FIELDS) + (
  73. User.USERNAME_FIELD,
  74. 'password',
  75. 'dyn',
  76. )