pythondjangodjango-rest-frameworkdjango-countriesdj-rest-auth

How to serialize a CountryField from django-countries?


I'm trying to add the CountryField to a serializer for the Register process (using dj-rest-auth) and can't find the correct way to implement it.

All the answers I found just say to use what the documentation says, but that doesn't help for me, maybe Im just not doing it right.

This is what the documentation of django-countries says:

from django_countries.serializers import CountryFieldMixin

class CountrySerializer(CountryFieldMixin, serializers.ModelSerializer):

class Meta:
    model = models.Person
    fields = ('name', 'email', 'country')

I need to add the field here:

class CustomRegisterSerializer(RegisterSerializer, CountryFieldMixin):

    birth_date = serializers.DateField()
    country = CountryField()
    gender = serializers.ChoiceField(choices=GENDER)

    # class Meta:
    #     model = User
    #     fields = ('country')

    # Define transaction.atomic to rollback the save operation in case of error
    @transaction.atomic
    def save(self, request):
        user = super().save(request)
        user.birth_date = self.data.get('birth_date')
        user.country = self.data.get('country')
        user.gender = self.data.get('gender')
        user.save()
        return user

User Model

class User(AbstractUser):
    """
    Default custom user model
    """

    name = models.CharField(max_length=30)

    birth_date = models.DateField(null=True, blank=True)
    country = CountryField(null=True, blank=True, blank_label='Select country')
    gender = models.CharField(choices=GENDER, max_length=6, null=True, blank=True)
    ...

I tried different things besides this and nothing worked.


Solution

  • For the serializer, you import the CountryField of the django_countries.serializer_fields module, so:

    from django_countries.serializer_fields import CountryField
    
    class CustomRegisterSerializer(RegisterSerializer):
        # …
        country = CountryField()
        # …

    If you instead want to work with the Mixin (which will use such CountryField serializer field), you should specify the CountryFieldMixin before the RegisterSerializer, otherwise it will not override the .build_standard_field(…) method.

    You thus inherit with:

    class CustomRegisterSerializer(CountryFieldMixin, RegisterSerializer):
        # …

    In that case you should not specify the country serializer field manually, since that will render the mixin ineffective.