def test_to_internal_uuid(self): """Tests that model instances are returned for a UUID.""" model = Mock() field = NestedRelatedField(model) uuid_ = uuid4() assert field.to_internal_value(uuid_) assert model.objects.all().get.call_args_list == [call(pk=uuid_)]
def test_to_representation_extra_fields_with_nested_related(self): """ Tests that if the field has a nested related field, `to_representation` returns '<nested-field>': {...} using the nested mapping. """ nested_pk = uuid4() nested_instance = Mock(id=nested_pk, pk=nested_pk, field1='field1_value') nested_field = NestedRelatedField( Mock(), extra_fields=('field1', ), ) instance_pk = uuid4() instance = Mock(id=instance_pk, pk=instance_pk, nested_instance=nested_instance) field = NestedRelatedField( Mock(), extra_fields=(('nested_instance', nested_field), ), ) assert field.to_representation(instance) == { 'id': str(instance.id), 'nested_instance': { 'id': str(nested_pk), 'field1': 'field1_value', }, }
def test_to_internal_str(self): """Tests that model instances are returned for a dict with an 'id' key.""" model = MagicMock() field = NestedRelatedField(model) uuid_ = uuid4() assert field.to_internal_value(str(uuid_)) assert model.objects.all().get.call_args_list == [call(pk=uuid_)]
def test_to_internal_non_existent_id(self): """Tests an id of a non-existent object raises an exception.""" model = MagicMock() model.objects().all.get.return_value = ObjectDoesNotExist field = NestedRelatedField(model) with pytest.raises(ValidationError): field.to_internal_value({})
class CompanyReferralSerializer(serializers.ModelSerializer): """Serialiser for company referrals.""" company = NestedRelatedField('company.Company') contact = NestedRelatedField('company.Contact', required=False, allow_null=True) created_by = NestedAdviserWithEmailAndTeamField(read_only=True) recipient = NestedAdviserWithEmailAndTeamField() class Meta: model = CompanyReferral fields = ( 'id', 'company', 'completed_on', 'contact', 'created_by', 'created_on', 'recipient', 'status', 'subject', 'notes', ) read_only_fields = ( 'id', 'completed_on', 'created_on', 'status', )
def get_one_list_group_tier(self, obj): """ :returns: the One List Tier for the group that company `obj` is part of. """ one_list_tier = obj.get_one_list_group_tier() field = NestedRelatedField(OneListTier) return field.to_representation(one_list_tier)
class AssignOneListTierAndGlobalAccountManagerSerializer(serializers.Serializer): """ Serializer for assigning One List tier and global account manager to a company. """ excluded_one_list_tier_id = OneListTierID.tier_d_international_trade_advisers.value default_error_messages = { 'cannot_assign_subsidiary_to_one_list': gettext_lazy('A subsidiary cannot be on One List.'), 'cannot_assign_company_one_list_tier': gettext_lazy('A company can only have this One List tier assigned by ITA.'), 'cannot_change_company_with_current_one_list_tier': gettext_lazy('A company on this One List tier can only be changed by ITA.'), } one_list_tier = NestedRelatedField(OneListTier) global_account_manager = NestedRelatedField(Advisor) def validate_one_list_tier(self, one_list_tier): """Validates new One List tier.""" if one_list_tier and one_list_tier.id == self.excluded_one_list_tier_id: raise serializers.ValidationError( self.error_messages['cannot_assign_company_one_list_tier'], code='cannot_assign_company_one_list_tier', ) return one_list_tier def validate(self, attrs): """ Validate that given one list tier and global account manager can be assigned to a company. """ attrs = super().validate(attrs) if self.instance.global_headquarters: raise serializers.ValidationError( self.error_messages['cannot_assign_subsidiary_to_one_list'], code='cannot_assign_subsidiary_to_one_list', ) old_one_list_tier = self.instance.one_list_tier if old_one_list_tier and old_one_list_tier.id == self.excluded_one_list_tier_id: raise serializers.ValidationError( self.error_messages['cannot_change_company_with_current_one_list_tier'], code='cannot_change_company_with_current_one_list_tier', ) return attrs def save(self, adviser): """Update company One List account manager and tier.""" self.instance.assign_one_list_account_manager_and_tier( self.validated_data['global_account_manager'], self.validated_data['one_list_tier'].id, adviser, ) return self.instance
def test_to_choices(self): """Tests that model choices are returned.""" model = Mock() uuid_ = uuid4() instance = Mock(id=uuid_, pk=uuid_) instance.name = 'instance name' model.objects.all.return_value = [instance] * 2 field = NestedRelatedField(model) assert (list(field.get_choices().items()) == [(str( instance.id), str(instance))] * 2)
def test_to_representation(self): """Tests that a model instance is converted to a dict.""" model = Mock() uuid_ = uuid4() instance = Mock(id=uuid_, pk=uuid_) instance.name = 'instance name' field = NestedRelatedField(model) assert field.to_representation(instance) == { 'id': str(instance.id), 'name': instance.name, }
class AssetClassInterestSerializer(ConstantModelSerializer): """Asset class interest serializer.""" asset_class_interest_sector = NestedRelatedField( AssetClassInterestSector, read_only=True, )
class CompaniesHouseCompanySerializerV4(serializers.ModelSerializer): """Companies House company serializer V4.""" registered_address = AddressSerializer( source_model=CompaniesHouseCompany, address_source_prefix='registered_address', ) business_type = NestedRelatedField('metadata.BusinessType') class Meta: model = CompaniesHouseCompany fields = ( 'id', 'business_type', 'company_category', 'company_number', 'company_status', 'incorporation_date', 'name', 'registered_address', 'sic_code_1', 'sic_code_2', 'sic_code_3', 'sic_code_4', 'uri', ) read_only_fields = fields
class InvestmentActivitySerializer(serializers.ModelSerializer): """Serializer for an Investment Activity.""" created_by = NestedAdviserField(read_only=True) modified_by = NestedAdviserField(read_only=True) text = serializers.CharField(required=True) activity_type = NestedRelatedField( InvestmentActivityType, default=default_activity_type, ) class Meta: model = InvestmentActivity fields = ( 'id', 'text', 'activity_type', 'created_by', 'created_on', 'modified_on', 'modified_by', ) read_only_fields = ( 'id', 'created_on', 'created_by', )
class InteractionDITParticipantSerializer(serializers.ModelSerializer): """ Interaction DIT participant serialiser. Used as a field in InteractionSerializer. """ adviser = NestedAdviserField() # team is read-only as it is set from the adviser when a participant is added to # an interaction team = NestedRelatedField(Team, read_only=True) @classmethod def many_init(cls, *args, **kwargs): """Initialises a many=True instance of the serialiser with a custom list serialiser.""" child = cls(context=kwargs.get('context')) return InteractionDITParticipantListSerializer(child=child, *args, **kwargs) class Meta: model = InteractionDITParticipant fields = ('adviser', 'team') # Explicitly set validator as extra protection against a unique together validator being # added. # (UniqueTogetherValidator would not function correctly when multiple items are being # updated at once.) validators = []
class NestedCompaniesHouseCompanySerializer(serializers.ModelSerializer): """Nested Companies House company serializer.""" registered_address_country = NestedRelatedField('metadata.Country') class Meta: model = CompaniesHouseCompany fields = ( 'id', 'company_category', 'company_number', 'company_status', 'incorporation_date', 'name', 'registered_address_1', 'registered_address_2', 'registered_address_county', 'registered_address_country', 'registered_address_town', 'registered_address_postcode', 'sic_code_1', 'sic_code_2', 'sic_code_3', 'sic_code_4', 'uri', ) read_only_fields = fields
class AddressRequestSerializer(DNBAddressSerializer): """ Validate address and convert it to the format expected by dnb-service. """ line_1 = serializers.CharField(source='address_line_1', required=False) town = serializers.CharField(source='address_town', required=False) country = NestedRelatedField(model=CountryModel, source='address_country', required=False)
class InteractionExportCountrySerializer(serializers.ModelSerializer): """InteractionExportCountry serializer.""" country = NestedRelatedField(Country) class Meta: model = InteractionExportCountry fields = ('country', 'status')
class PublicOrderSerializer(serializers.ModelSerializer): """DRF serializer for public facing API.""" primary_market = NestedRelatedField(Country) uk_region = NestedRelatedField(UKRegion) company = NestedRelatedField(Company) contact = NestedRelatedField(Contact) billing_address_country = NestedRelatedField(Country) class Meta: model = Order fields = ( 'public_token', 'reference', 'status', 'created_on', 'company', 'contact', 'primary_market', 'uk_region', 'contact_email', 'contact_phone', 'vat_status', 'vat_number', 'vat_verified', 'po_number', 'discount_value', 'net_cost', 'subtotal_cost', 'vat_cost', 'total_cost', 'billing_company_name', 'billing_contact_name', 'billing_email', 'billing_phone', 'billing_address_1', 'billing_address_2', 'billing_address_town', 'billing_address_county', 'billing_address_postcode', 'billing_address_country', 'paid_on', 'completed_on', ) read_only_fields = fields
class OneListCoreTeamMemberModelSerializer(UniqueAdvisersBaseSerializer): """One List Core Team Member model serializer.""" adviser = NestedAdviserField() company = NestedRelatedField(Company, read_only=True) class Meta(UniqueAdvisersBaseSerializer.Meta): model = OneListCoreTeamMember fields = ('adviser', 'company')
class NestedInvestmentProjectStageLogSerializer(serializers.ModelSerializer): """Serialiser for investment project stage log.""" stage = NestedRelatedField(meta_models.InvestmentProjectStage, read_only=True) created_on = serializers.DateTimeField(read_only=True) class Meta: model = InvestmentProjectStageLog fields = ('stage', 'created_on')
class SectorSerializer(serializers.Serializer): """Sector serializer.""" id = serializers.ReadOnlyField() name = serializers.ReadOnlyField() segment = serializers.ReadOnlyField() parent = NestedRelatedField('metadata.Sector', read_only=True) level = serializers.ReadOnlyField() disabled_on = serializers.ReadOnlyField()
class CompanyExportCountrySerializer(serializers.ModelSerializer): """ Export country serializer holding `Country` and its status. """ country = NestedRelatedField(meta_models.Country) class Meta: model = CompanyExportCountry fields = ('country', 'status')
def test_to_representation_extra_fields_with_nested_related_none(self): """ Tests that if the field has a nested related field and its value is None, `to_representation` returns '<nested-field>': None. """ nested_field = NestedRelatedField( Mock(), extra_fields=('field1', ), ) instance_pk = uuid4() instance = Mock(id=instance_pk, pk=instance_pk, nested_instance=None) field = NestedRelatedField( Mock(), extra_fields=(('nested_instance', nested_field), ), ) assert field.to_representation(instance) == { 'id': str(instance.id), 'nested_instance': None, }
class CompaniesHouseCompanySerializer(NestedCompaniesHouseCompanySerializer): """Full Companies House company serializer.""" business_type = NestedRelatedField('metadata.BusinessType') class Meta(NestedCompaniesHouseCompanySerializer.Meta): fields = ( *NestedCompaniesHouseCompanySerializer.Meta.fields, 'business_type', ) read_only_fields = fields
def test_to_choices_limit(self): """Tests that model choices are limited and returned.""" model = Mock() uuid_ = uuid4() instance = Mock(id=uuid_, pk=uuid_) instance.name = 'instance name' model.objects.all.return_value = [instance] * 2 field = NestedRelatedField(model) assert list(field.get_choices(1).items()) == [( str(instance.id), str(instance), )] @pytest.mark.parametrize( 'input_website,expected_website', ( ('www.google.com', 'http://www.google.com'), ('http://www.google.com', 'http://www.google.com'), ('https://www.google.com', 'https://www.google.com'), ('', ''), ), ) def test_url_field_input(self, input_website, expected_website): """Tests that RelaxedURLField prepends http:// when one is not provided.""" assert RelaxedURLField().run_validation( input_website) == expected_website @pytest.mark.parametrize( 'input_website,expected_website', ( ('www.google.com', 'http://www.google.com'), ('http://www.google.com', 'http://www.google.com'), ('https://www.google.com', 'https://www.google.com'), ('', ''), ), ) def test_url_field_output(self, input_website, expected_website): """Tests that RelaxedURLField prepends http:// when one is not stored.""" assert RelaxedURLField().to_representation( input_website) == expected_website
class TeamWithRegionSerializer(serializers.ModelSerializer): """DRF serializer for teams with region.""" uk_region = NestedRelatedField(Team, read_only=True) class Meta: model = Team fields = ( 'id', 'name', 'uk_region', ) read_only_fields = fields
class InvoiceSerializer(serializers.ModelSerializer): """Invoice DRF serializer.""" invoice_address_country = NestedRelatedField(Country) billing_address_country = NestedRelatedField(Country) class Meta: model = Invoice fields = ( 'created_on', 'invoice_number', 'invoice_company_name', 'invoice_address_1', 'invoice_address_2', 'invoice_address_town', 'invoice_address_county', 'invoice_address_postcode', 'invoice_address_country', 'invoice_vat_number', 'payment_due_date', 'billing_contact_name', 'billing_company_name', 'billing_address_1', 'billing_address_2', 'billing_address_county', 'billing_address_postcode', 'billing_address_town', 'billing_address_country', 'po_number', 'vat_status', 'vat_number', 'vat_verified', 'net_cost', 'subtotal_cost', 'vat_cost', 'total_cost', ) read_only_fields = fields
class InteractionDITParticipantSerializer(UniqueAdvisersBaseSerializer): """ Interaction DIT participant serialiser. Used as a field in InteractionSerializer. """ # team is read-only as it is set from the adviser when a participant is added to # an interaction team = NestedRelatedField(Team, read_only=True) class Meta(UniqueAdvisersBaseSerializer.Meta): model = InteractionDITParticipant fields = ('adviser', 'team')
class AssignRegionalAccountManagerSerializer(serializers.Serializer): """ Serialiser for assigning an international trade adviser as the account manager of a company. """ target_one_list_tier_id = OneListTierID.tier_d_international_trade_advisers.value default_error_messages = { 'cannot_change_account_manager_of_one_list_subsidiary': gettext_lazy( "A lead adviser can't be set on a subsidiary of a One List company." ), 'cannot_change_account_manager_for_other_one_list_tiers': gettext_lazy( "A lead adviser can't be set for companies on this One List tier." ), } regional_account_manager = NestedRelatedField(Advisor) def validate(self, attrs): """Validate that the change of One List account manager and tier is allowed.""" attrs = super().validate(attrs) global_headquarters = self.instance.global_headquarters if global_headquarters and global_headquarters.one_list_tier_id: raise serializers.ValidationError( self.error_messages[ 'cannot_change_account_manager_of_one_list_subsidiary'], code='cannot_change_account_manager_of_one_list_subsidiary', ) if self.instance.one_list_tier_id not in ( None, self.target_one_list_tier_id): raise serializers.ValidationError( self.error_messages[ 'cannot_change_account_manager_for_other_one_list_tiers'], code='cannot_change_account_manager_for_other_one_list_tiers', ) return attrs def save(self, adviser): """Update the company's One List account manager and tier.""" self.instance.assign_one_list_account_manager_and_tier( self.validated_data['regional_account_manager'], self.target_one_list_tier_id, adviser, ) return self.instance
def test_to_representation_extra_fields(self): """Tests that a model instance is converted to a dict with extra fields.""" model = Mock() uuid_ = uuid4() uuid2_ = uuid4() instance = Mock(id=uuid_, pk=uuid_, test_field='12as', test2=uuid2_, test3='10') field = NestedRelatedField( model, extra_fields=( 'test_field', 'test2', ('test3', IntegerField()), ), ) assert field.to_representation(instance) == { 'id': str(instance.id), 'test_field': instance.test_field, 'test2': uuid2_, 'test3': 10, }
class CancelOrderSerializer(OrderSerializer): """DRF serializer for cancelling an order.""" cancellation_reason = NestedRelatedField(CancellationReason) class Meta: model = Order fields = ('cancellation_reason', ) def cancel(self): """Cancel an order.""" self.instance.cancel( by=self.context['current_user'], reason=self.validated_data['cancellation_reason'], ) return self.instance