0

I'm trying to register a user and have the email part go into the user name from the Members model, but I'm getting the above error.

In auth_user username Equals [blablabla]@gmail.. in brackets I'm trying to add the same to the Members user, for a ForeignKey relationship. To make user equal to blablabla

Serializers

class RegisterSerializer(serializers.ModelSerializer):
password1 = serializers.CharField(required=True)
password2 = serializers.CharField(required=True)
user = serializers.HiddenField(default=serializers.CurrentUserDefault())

class Meta:
    model = Members
    fields = ('first_name', 'last_name', 'user', 'email', 'photo', 'gender', 'password1', 'password2')

def validate_email(self, email):
    email = get_adapter().clean_email(email)
    if allauth_settings.UNIQUE_EMAIL:
        if email and email_address_exists(email):
            raise serializers.ValidationError("A user is already registered with this email address.")
    return email

def validate_password1(self, password):
    return get_adapter().clean_password(password)

def validate(self, data):
    if data['password1'] != data['password2']:
        raise serializers.ValidationError("The two password fields didn't match.")
    return data

def get_cleaned_data(self):

    return {
        'password1': self.validated_data.get('password1', ''),
        'email': self.validated_data.get('email', ''),
    }, {
        'first_name': self.validated_data.get('first_name', ''),
        'last_name': self.validated_data.get('last_name', ''),
        'photo': self.validated_data.get('photo', ''),
        'gender': self.validated_data.get('gender', ''),
        'email': self.validated_data.get('email', ''),
        'user': self.validated_data.get('user', ''),
    }

def save(self, request):
    adapter = get_adapter()
    user = adapter.new_user(request)
    self.cleaned_data, data_for_members = self.get_cleaned_data()
    Members.objects.create(**data_for_members)
    adapter.save_user(request, user, self)
    setup_user_email(request, user, [])
    user.save()
    return user

class LoginSerializer(RestAuthLoginSerializer): username = None

Models

class Members(models.Model):
user = models.OneToOneField(User, null=True, on_delete=models.CASCADE)
photo = models.ImageField(upload_to='photos/%Y/%m/%d/')
gender_choices = (('F', 'Female'), ('M', 'Man'), ('U', 'Undefined'))
gender = models.CharField(max_length=1, choices=gender_choices, default='U')
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
email = models.EmailField()

def save(self, *args, **kwargs):
    super(Members, self).save(*args, **kwargs)
    img = self.photo
    print(img, 321)
    watermark(img)
James Z
  • 12,209
  • 10
  • 24
  • 44
  • I think the problem might be with the default value you're providing in the serializer class. It is taking the current user by default. When registering, the user is not logged in, so it is `AnonymousUser`. This hides the actual problem, the `user` does not get passed correctly in the request. – vinkomlacic Mar 20 '22 at 18:29
  • Edit your question correctly with`indentation` in code. – Sunderam Dubey Mar 21 '22 at 02:29

1 Answers1

0

I went the other way and changed my goals a little. Thanks https://stackoverflow.com/a/38553202/18521916 The problem was that the allauth adapter didn't save the extra fields and I explicitly store them in these two lines:

user.gender = self.cleaned_data.get('gender')
user.photo = self.cleaned_data.get('photo')

Another solution is to override the adapter

Serializers

from rest_framework import serializers
from api_dating.models import Members

from allauth.account.adapter import get_adapter
from allauth.account.utils import setup_user_email


class CustomRegisterSerializer(serializers.ModelSerializer):
    password1 = serializers.CharField(write_only=True)
    password2 = serializers.CharField(write_only=True)

    class Meta:
        model = Members
        fields = ['username', 'email', 'first_name', 'last_name', 'password1', 'password2', 'photo', 'gender']

    def get_cleaned_data(self):
        return {
            'password1': self.validated_data.get('password1', ''),
            'email': self.validated_data.get('email', ''),
            'first_name': self.validated_data.get('first_name', ''),
            'last_name': self.validated_data.get('last_name', ''),
            'username': self.validated_data.get('username', ''),
            'photo': self.validated_data.get('photo', ''),
            'gender': self.validated_data.get('gender', ''),
        }

    def save(self, request):
        adapter = get_adapter()
        user = adapter.new_user(request)
        self.cleaned_data = self.get_cleaned_data()
        adapter.save_user(request, user, self)
        setup_user_email(request, user, [])

        user.gender = self.cleaned_data.get('gender')
        user.photo = self.cleaned_data.get('photo')

        user.save()
        return user

Models

from django.contrib.auth.models import AbstractUser
from django.db import models


class Members(AbstractUser):
    photo = models.ImageField(upload_to='photos/%Y/%m/%d/')
    gender_choices = (('F', 'Female'), ('M', 'Male'), ('U', 'Undefined'))
    gender = models.CharField(max_length=1, choices=gender_choices, default='U')

Settings

Apps
...    
'rest_framework',
'rest_framework.authtoken',
'dj_rest_auth',
'dj_rest_auth.registration',
'django.contrib.sites',
'allauth',
'allauth.account',
'allauth.socialaccount',
    
AUTH_USER_MODEL = 'api_dating.Members'

EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'

REST_AUTH_REGISTER_SERIALIZERS = {
    'REGISTER_SERIALIZER': 'api_dating.serializers.CustomRegisterSerializer',
}

SITE_ID = 1