django-countries: Field is not serializeable with Django Rest Framework

Hello,

I have encountered an issues when working with the country field and Django Rest Framwork. If in the models we have a field that can be set to blank:

country = CountryField(_('country'), blank=True, null=True, default='NL')

when used as a normal field in the serializer I get an error that: TypeError: Country(code=u’') is not JSON serializable. This happens only when the country field is blank.

It has been reported by someone else also on the django rest framework group. https://groups.google.com/forum/#!topic/django-rest-framework/3hrS2xr6BS0

I am not sure exactly if this can be solved on the django rest framework side but thought to report it here also. It might be solved on the django-countries side.

Thanks, Vlad

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Comments: 30 (8 by maintainers)

Commits related to this issue

Most upvoted comments

@SmileyChris I had the same issue as @rschwiebert did and @jgeerds suggestion helped.

I was using: from django_countries.fields import CountryField When I should have been using: from django_countries.serializer_fields import CountryField

I think it would be helpful to add the correct import statement needed in the the code section of “Django Rest Framework field” on the readme as it wasn’t obvious since it’s the same name as the Django field.

@rschwiebert It works for me. Are you sure you’re using the right serializer?

from django_countries.serializer_fields import CountryField

class FoobarSerializer(serializers.ModelSerializer):
    country = CountryField()

    class Meta:
        model = Foobar
        fields = ('country', )

I think the country field is translated into a serializers.ChoiceField. It works well if i have a country, but if it is not then it gets the error.

How is solved it for my case: I have a CompanySerializer and i overwrote the country field with a custom serializer. The default one would have been a serializers.ChoiceField:

class SerializableCountryField(serializers.ChoiceField):
    def __init__(self, **kwargs):
        super(SerializableCountryField, self).__init__(choices=Countries())

    def to_representation(self, value):
        if value in ('', None):
            return '' # normally here it would return value. which is Country(u'') and not serialiable
        return super(SerializableCountryField, self).to_representation(value)

class CustomerSerializerV2(serializers.ModelSerializer):
    country = SerializableCountryField(allow_blank=True)

    class Meta:
        model = Company
        fields = ('id', 'name', ''postal_code', 'address', 'city', 'country')

In the to_representaion method of the SerializableCountryField i returned and empty string instead of the normal ‘value’ variable. The value in that case is Countru(u’') which is not serializable.

I hope this helped?

this error come in multi-select countries. to fix it just add CountryFieldMixin in the serializer eg: class MySerializer(CountryFieldMixin, serializers.ModelSerializer)

Hello!

I found that this from django_countries.serializer_fields import CountryField doesn’t work with CountryField(multiple=True) because “to_representation” method doesn’t work with lists. So I wrote my own class:

class MultiCountry(CountryField):
    def to_representation(self, obj):
        countries = []
        for item in obj:
            code = self.countries.alpha2(item)
            if not code:
                countries.append({"code": ""})
            if not self.country_dict:
                countries.append({"code": code})
            if self.country_dict:
                countries.append({"code": code, "name": force_str(self.countries.name(item))})
        return countries

Am I right or misunderstood somethign?

Forgot to say that I need code+name presentation