class PlanSerializer(serializers.HyperlinkedModelSerializer): metered_features = MeteredFeatureSerializer(required=False, many=True) provider = serializers.HyperlinkedRelatedField( queryset=Provider.objects.all(), view_name='provider-detail', ) product_code = ProductCodeRelatedField() class Meta: model = Plan fields = ('name', 'url', 'interval', 'interval_count', 'amount', 'currency', 'trial_period_days', 'generate_after', 'enabled', 'private', 'product_code', 'metered_features', 'provider') def validate_metered_features(self, value): metered_features = [] for mf_data in value: metered_features.append(MeteredFeature(**mf_data)) try: Plan.validate_metered_features(metered_features) except ValidationError, e: raise serializers.ValidationError(str(e)[3:-2]) return value
class PlanSerializer(serializers.ModelSerializer): metered_features = MeteredFeatureSerializer( required=False, many=True ) provider = serializers.PrimaryKeyRelatedField( queryset=Provider.objects.all() ) product_code = ProductCodeRelatedField() class Meta: model = Plan fields = ('name', 'url', 'interval', 'interval_count', 'amount', 'currency', 'trial_period_days', 'generate_after', 'enabled', 'private', 'product_code', 'metered_features', 'provider') def validate_metered_features(self, value): metered_features = [] for mf_data in value: metered_features.append(MeteredFeature(**mf_data)) try: Plan.validate_metered_features(metered_features) except ValidationError as e: raise serializers.ValidationError(str(e)[3:-2]) return value def create(self, validated_data): metered_features_data = validated_data.pop('metered_features') metered_features = [] for mf_data in metered_features_data: mf = MeteredFeatureSerializer(data=mf_data) mf.is_valid(raise_exception=True) mf = mf.create(mf.validated_data) metered_features.append(mf) product_code = validated_data.pop('product_code') product_code.save() validated_data.update({'product_code': product_code}) plan = Plan.objects.create(**validated_data) plan.metered_features.add(*metered_features) plan.product_code = product_code plan.save() return plan def update(self, instance, validated_data): instance.name = validated_data.get('name', instance.name) instance.generate_after = validated_data.get('generate_after', instance.generate_after) instance.due_days = validated_data.get('due_days', instance.due_days) instance.save() return instance
class MeteredFeatureSerializer(serializers.ModelSerializer): product_code = ProductCodeRelatedField() linked_feature = RelatedPropertyField(related_lookup="product_code__value", queryset=MeteredFeature.objects.all(), required=False, allow_null=True) included_units_calculation = serializers.CharField(required=False, allow_null=True) class Meta: model = MeteredFeature fields = ('name', 'unit', 'price_per_unit', 'included_units', 'product_code', 'included_units_calculation', 'linked_feature', 'prebill_included_units',) extra_kwargs = { 'included_units_calculation': {'required': False}, 'linked_feature': {'required': False}, 'prebill_included_units': {'required': False}, } def create(self, validated_data): product_code = validated_data.pop('product_code') product_code.save() validated_data.update({'product_code': product_code}) metered_feature = MeteredFeature.objects.create(**validated_data) return metered_feature def to_representation(self, instance): """ Remove some additional fields if no value is set. """ from collections import OrderedDict EMPTY_VALUES = ['', None, [], ()] EXCLUDABLE = self.Meta.extra_kwargs.items() ret = super().to_representation(instance) return OrderedDict( ( (name, value) for name, value in ret.items() if value not in EMPTY_VALUES and name not in EXCLUDABLE ) )
class MeteredFeatureSerializer(serializers.ModelSerializer): product_code = ProductCodeRelatedField() class Meta: model = MeteredFeature fields = ('name', 'unit', 'price_per_unit', 'included_units', 'product_code') def create(self, validated_data): product_code = validated_data.pop('product_code') product_code.save() validated_data.update({'product_code': product_code}) metered_feature = MeteredFeature.objects.create(**validated_data) return metered_feature