0
votes

I am using a custom register serializer in django-rest-auth to add new fields on registration.

I have a country model and a country field in the user model that is an FK to countries.

user.models

@python_2_unicode_compatible
class User(AbstractUser):
    phone = models.CharField(max_length=15, null=True)
    verified_phone = models.BooleanField(default=False)
    country = models.ForeignKey(Country, related_name='country')
    level = models.ForeignKey(UserLevel, related_name='user_level')

user.serializers

class UserModelSerializer(HyperlinkedModelSerializer):
    class Meta:
        model = User
        country = serializers.ReadOnlyField(source='country.name')
        fields = [
            'url',
            'id',
            'username',
            'country',
            'email',
            'phone',
        ]
        read_only_fields = (
            'id',
            'password',
        )

custom register serializer

class CustomRegisterSerializer(RegisterSerializer):
    country = serializers.PrimaryKeyRelatedField(read_only=True)

    def get_cleaned_data(self):
        return {
            'country': self.validated_data.get('country', ''),
            'password1': self.validated_data.get('password1', ''),
            'email': self.validated_data.get('email', ''),
            'username': self.validated_data.get('username', ''),
    }

    def save(self, request):
        print(self.get_cleaned_data())
        adapter = get_adapter()
        user = adapter.new_user(request)
        user.country = self.validated_data.get('country',  '')
        self.cleaned_data = self.get_cleaned_data()
        adapter.save_user(request, user, self)
        setup_user_email(request, user, [])
        user.save()
        return user

Sample data that is sent from the client with the country as an object

{username: "bernie", email: "[email protected]", country: {…}, password1: "password", password2: "password"}

but this error keeps coming,

Cannot assign "''": "User.country" must be a "Country" instance.

when I printed the request on the console this is what I got

{'country': '', 'password1': 'password', 'email': '[email protected]', 'username': 'bernie'}

which means that somewhere along the line, the country data is lost.

I have tried sending only the id, name of the country and nothing works. What am I doing wrong?

2

2 Answers

4
votes

user.country = self.validated_data.get('country', '')

This is the problematic line.

You should pass the Country object instead of just a string. For example:

country_obj = Country.objects.get(name=self.validated_data.get('country', '')) user.country = country_obj

Of course make sure the specific Country was created before and is existing before retrieving it as an object.

1
votes

I have had a similar issue, with a similar warning. In your case it can be fixed by providing an instance of Country. If Country is an empty string then use a corresponding Country constructor with an empty string: user.country = Country('')