web-dev-qa-db-fra.com

Django inscription rest-auth allauth avec email, prénom et nom, et sans nom d'utilisateur

J'utilise Django-rest-auth et allauth pour la connexion et l'enregistrement dans mon Django. Je n'ai écrit aucune ligne supplémentaire de mon propre code pour la connexion ou l'inscription. L'inscription est réussie avec emailid et mot de passe fourni.

Je n'utilise pas de nom d'utilisateur pour l'authentification, mais plutôt un e-mail.

Dans mon api navigable pour l'enregistrement, je reçois ce qui suit:

enter image description here

En plus de ces champs, je veux avoir first_name et last_name (la table par défaut auth_user avait ces colonnes) afin que mon nouvel auth_user ait également ces champs définis avec l'email et le mot de passe haché.

Comment puis-je atteindre cet objectif? Ce formulaire consultable en lui-même n'est pas si important mais être capable de stocker prénom et nom est ce dont j'ai besoin principalement.

23
Thinker
  1. Assurez-vous que vous avez ACCOUNT_USERNAME_REQUIRED = False dans votre settings.py fichier.

  2. Pour first_name et last_name vous devez écrire un RegisterSerializer personnalisé ( https://github.com/Tivix/Django-rest-auth/blob/master/rest_auth/registration/serializers.py#L166 =)

voici un exemple de code pour serializers.py

from allauth.account import app_settings as allauth_settings
from allauth.utils import email_address_exists
from allauth.account.adapter import get_adapter
from allauth.account.utils import setup_user_email

class RegisterSerializer(serializers.Serializer):
    email = serializers.EmailField(required=allauth_settings.EMAIL_REQUIRED)
    first_name = serializers.CharField(required=True, write_only=True)
    last_name = serializers.CharField(required=True, write_only=True)
    password1 = serializers.CharField(required=True, write_only=True)
    password2 = serializers.CharField(required=True, write_only=True)

    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 e-mail 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 {
            'first_name': self.validated_data.get('first_name', ''),
            'last_name': self.validated_data.get('last_name', ''),
            'password1': self.validated_data.get('password1', ''),
            'email': self.validated_data.get('email', ''),
        }

    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.profile.save()
        return user
  1. Dans settings.py assurez-vous d'ajouter pour faire référence au nouveau sérialiseur.

    REST_AUTH_REGISTER_SERIALIZERS = {
            'REGISTER_SERIALIZER': 'path.to.RegisterSerializer',
    }
    
31
girish

Vous pouvez également simplement remplacer le custom_signup méthode sur RegisterSerializer, prévue à cet effet.

from rest_auth.registration.serializers import RegisterSerializer
from rest_auth.registration.views import RegisterView
from rest_framework import serializers


class NameRegistrationSerializer(RegisterSerializer):

  first_name = serializers.CharField(required=False)
  last_name = serializers.CharField(required=False)

  def custom_signup(self, request, user):
    user.first_name = self.validated_data.get('first_name', '')
    user.last_name = self.validated_data.get('last_name', '')
    user.save(update_fields=['first_name', 'last_name'])


class NameRegistrationView(RegisterView):
  serializer_class = NameRegistrationSerializer

Utilisez ensuite ce qui suit dans votre urls.py

url(r'^rest-auth/registration/name-registration/$', NameRegistrationView.as_view(), name="rest_name_register")

ou définissez REGISTER_SERIALIZER dans settings.py

REST_AUTH_REGISTER_SERIALIZERS = {
    'REGISTER_SERIALIZER': 'path.to.RegisterSerializer',
}
15
Tritlo

Une solution plus élégante consisterait à hériter de RegisterSerializer et à l'étendre au besoin.

class MyRegisterSerializer(RegisterSerializer):
    first_name = serializers.CharField(required=True, write_only=True)
    last_name = serializers.CharField(required=True, write_only=True)

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

    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.save()
        return user
10
Anand Ramani