Django allauth signup without password
Asked Answered
J

4

9

Is it possible to create user accounts with email as username and no other details such as password using allauth? The intention is to make the signup process as easy as possible. Can password be skipped on signup and be updated on email confirmation?. I have tried this scenario in python shell (./manage.py shell) and had successfull outputs.

In [1]: from django.contrib.auth.models import User

In [2]: User.objects.create(username='nopass')
Out[2]: <User: nopass>

In [3]: User.objects.all()
Out[3]: [<User: userone>, <User: nopass>] 
In [4]: usr=User.objects.all()[1]
In [5]: usr.set_password('pwdnotset')
In [6]: usr.save()
In [7]: from django.contrib.auth import authenticate
In [8]: authenticate(username='nopass',password='pwdnotset')
Out[8]: <User: nopass>

I have referred to this link and found that there was no such settings for allauth at that time. However reply was posted at 2013. It would be helpful if a way to create user without password on signup with some allauth configuration is devised. Thanks in advance.

Jordain answered 23/2, 2016 at 14:23 Comment(2)
did you find an ansewer?Effects
I think you can solve this by writing an allauth adapter for that. Let me browse thru my code repo again. If I found that I will post it here. :)Jordain
J
2

I think this will solve your issue: create a signup form with an overridden signup() method which sets an unusable password to user, and tell allauth to use that form for signup process.

Create a signup form by and override signup() like one given below:

class UserCreationForm(forms.ModelForm):
    username = forms.CharField(label=_("username"))
    # declare other fields also
    ...
    def signup(self, request, user):
        user.username = self.cleaned_data['username']
        # make sure you are saving all needed data for user model.
        user.set_unusable_password()
        user.save()

in settings.py, tell allauth to use that form for signup

ACCOUNT_SIGNUP_FORM_CLASS = 'yourapp.forms.UserCreationForm'

Below given is an ipdb stack trace for above context.

     48         import ipdb;ipdb.set_trace();
---> 49         user.email = self.cleaned_data['email']
     50         user.username = self.cleaned_data['username']

ipdb> user
<User: test_user>

ipdb> user.save()
*** IntegrityError: NOT NULL constraint failed: user.password

ipdb> user.set_unusable_password()
ipdb> user.save()
ipdb> user
<User: test_user>
ipdb> 
Jordain answered 26/12, 2017 at 15:4 Comment(1)
Yes and that was a few years before. I overrided some view and forms (sign-up view) to implement it. May be new version of allauth have this function. I am not sure. Code posted above was used to resolve the issue.Jordain
D
1

I don't see a way to do this in allauth as of yet, except by customizing the code for your project.

Contrary to what other answers say, the code in allauth.account.forms makes the SignUpForm inherit from your custom sign-up form:

# in allauth.account.forms.py
class BaseSignupForm(_base_signup_form_class()):

BaseSignupForm is used for both "standard" sign-up and social account sign-up. In "standard" sign-up, it subclasses as SignupForm and adds the password fields:

# in allauth.account.forms.py
class SignupForm(BaseSignupForm):
def __init__(self, *args, **kwargs):
    super(SignupForm, self).__init__(*args, **kwargs)
    self.fields['password1'] = PasswordField(label=_("Password"))
    if app_settings.SIGNUP_PASSWORD_ENTER_TWICE:
        self.fields['password2'] = PasswordField(
            label=_("Password (again)"))

So, I tried to hide the field in the view template, but no luck. Maybe using a FormHelper in crispyforms is the way.

Dunford answered 8/1, 2018 at 17:42 Comment(0)
A
1

One option is to make a custom signup view, and override the signup template to post to your custom view. In that view, you can use your own SignupForm that does not require a password.

Form:

class CustomUserCreationForm(forms.ModelForm):

    class Meta:
        model = CustomUser
        fields = ('email',)

    def save(self, commit=True):
        instance = super().save(commit=False)
        instance.set_unusable_password()
        if commit:
            instance.save()
        return instance

View:

class MySignupView(SignupView):
    form_class = CustomUserCreationForm

Url:

path('accounts/signup/custom/', MySignupView.as_view(), name="account_signup_custom"),

signup.html:

<form method="post" action="{% url 'account_signup_custom' %}">
Atrice answered 7/8, 2019 at 21:40 Comment(0)
A
0

You need to use modify the setting ACCOUNT_FORMS, (which is different from ACCOUNT_SIGNUP_FORM_CLASS which is only used for any additional fields).

In your settings.py, modify ACCOUNT_FORMS["signup"] like this, replacing appname with your application name:

ACCOUNT_FORMS = {
    'signup': 'appname.signup_forms.CustomSignupForm`,
}

Create a file named signup_forms.py in your app's directory. It's better to use a separate file from your usual forms.py to prevent a circular import. Type the following in your signup_forms.py file:

import allauth.account.forms

class CustomSignupForm(allauth.account.forms.SignupForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        del self.fields["password1"]
Amritsar answered 26/8, 2024 at 22:15 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.