DEV Community

Cover image for Create Advanced User Sign Up View in Django | Step-by-Step
codepylot
codepylot

Posted on • Updated on

Create Advanced User Sign Up View in Django | Step-by-Step

By Reverse Python

Youtube Channel with video tutorials - Reverse Python Youtube

Hello DEV Network!

In this tutorial we will cover advanced user registration view with Django.

First let's build basic sign up view then we are going to add some extra fields and confirmation mail function to make it advanced.

I am assuming that you already created your Django project.

Basic Registration

Django authentication framework provides a form named UserCreationForm (which inherits from ModelForm class) to handle the creation of new users. It has three fields namely username, password1 and password2 (for password confirmation).

In your views.py:

from django.shortcuts import render
from django.contrib.auth import login, authenticate
from django.contrib.auth.forms import UserCreationForm
from django.shortcuts import render, redirect

def home_view(request):
    return render(request, 'home.html')

def signup_view(request):
    form = UserCreationForm(request.POST)
    if form.is_valid():
        form.save()
        username = form.cleaned_data.get('username')
        password = form.cleaned_data.get('password1')
        user = authenticate(username=username, password=password)
        login(request, user)
        return redirect('home')
    return render(request, 'signup.html', {'form': form})
Enter fullscreen mode Exit fullscreen mode

cleaned_data is holding the validated form data and authenticate() method takes credentials as keyword arguments, username and password for the default case, checks them against each authentication backend, and returns a User object if the credentials are valid for a backend.

Once user is verified, login() method takes an HttpRequest object and a User object and saves the user’s ID in the session, using Django’s session framework. Finally, redirect() method is basically redirecting the logged in user to home URL.

urls.py

from django.contrib import admin
from django.urls import path
from accounts.views import home_view, signup_view

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', home_view, name="home"),
    path('signup/', signup_view, name="signup")
]

Enter fullscreen mode Exit fullscreen mode

Last step for basic registration, in your signup.html template:

<h2>Sign up Form</h2>
<form method="post">
  {% csrf_token %}
  {% for field in form %}
    <p>
      {{ field.label_tag }}<br>
      {{ field }}
      {% if field.help_text %}
        <small style="color: grey">{{ field.help_text }}</small>
      {% endif %}
      {% for error in field.errors %}
        <p style="color: red">{{ error }}</p>
      {% endfor %}
    </p>
  {% endfor %}
  <button type="submit">Sign up</button>
</form>
Enter fullscreen mode Exit fullscreen mode

We are displaying each field in our form with help texts to avoid errors. If any errors occurs while registration it is nice to display user what causes these errors.

sign up with Django

Registration with extra fields

What if we want register user with email or username? So, create forms.py and extend the UserCreationForm.

from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm


class SignUpForm(UserCreationForm):
    username = forms.CharField(max_length=30)
    email = forms.EmailField(max_length=200)

    class Meta:
        model = User
        fields = ('username', 'email', 'password1', 'password2', )
Enter fullscreen mode Exit fullscreen mode

Then , just change the UserCreationForm to SignUpForm in views.py:

from django.shortcuts import render
from django.contrib.auth import login, authenticate
from .forms import SignUpForm
from django.shortcuts import render, redirect

def home_view(request):
    return render(request, 'home.html')

def signup_view(request):
    form = SignUpForm(request.POST)
    if form.is_valid():
        form.save()
        username = form.cleaned_data.get('username')
        password = form.cleaned_data.get('password1')
        user = authenticate(username=username, password=password)
        login(request, user)
        return redirect('home')
    else:
        form = SignUpForm()
    return render(request, 'signup.html', {'form': form})
Enter fullscreen mode Exit fullscreen mode

That's it! Now, user can register by his/her username and email as well.

Registration with Profile Model

In my view, this is the best and recommended way to implement registration system in your Django application. We are going to use Django Signals to create a user profile right after user registered. So, take a look models.py

from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    first_name = models.CharField(max_length=100, blank=True)
    last_name = models.CharField(max_length=100, blank=True)
    email = models.EmailField(max_length=150)
    bio = models.TextField()

    def __str__(self):
        return self.user.username

@receiver(post_save, sender=User)
def update_profile_signal(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)
    instance.profile.save()
Enter fullscreen mode Exit fullscreen mode

With the @receiver decorator, we can link a signal with a function. So, every time that a User model instance ends to run its save() method (or when user register ends), the update_profile_signal will start to work right after user saved.

  • sender - The model class.
  • instance - The actual instance being saved.
  • created - A boolean; True if a new record was created.

Well, we want from user to enter his/her information into extra fields above to complete registration. Let's update forms.py :

from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User

class SignUpForm(UserCreationForm):
    first_name = forms.CharField(max_length=100, help_text='Last Name')
    last_name = forms.CharField(max_length=100, help_text='Last Name')
    email = forms.EmailField(max_length=150, help_text='Email')


    class Meta:
        model = User
        fields = ('username', 'first_name', 'last_name',
'email', 'password1', 'password2',)
Enter fullscreen mode Exit fullscreen mode

and in views.py:

from django.shortcuts import render
from django.contrib.auth import login, authenticate
from .forms import SignUpForm
from django.shortcuts import render, redirect

def home_view(request):
    return render(request, 'home.html')

def signup_view(request):
    form = SignUpForm(request.POST)
    if form.is_valid():
        user = form.save()
        user.refresh_from_db()
        user.profile.first_name = form.cleaned_data.get('first_name')
        user.profile.last_name = form.cleaned_data.get('last_name')
        user.profile.email = form.cleaned_data.get('email')
        user.save()
        username = form.cleaned_data.get('username')
        password = form.cleaned_data.get('password1')
        user = authenticate(username=username, password=password)
        login(request, user)
        return redirect('home')
    else:
        form = SignUpForm()
    return render(request, 'signup.html', {'form': form})
Enter fullscreen mode Exit fullscreen mode

We are using refresh_from_db() method to handle synchronism issue, basically reloading the database after the signal, so by this method our profile instance will load. Once profile instance loaded, set the cleaned data to the fields and save the user model.

Registration with Confirmation Mail

At this stage, we are going to configure email backend to send confirmation links. Let's test it on console for this tutorial.

Add the following line to your settings.py:

EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
Enter fullscreen mode Exit fullscreen mode

Then, update models.py by adding confirmation check field.

from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    first_name = models.CharField(max_length=100, blank=True)
    last_name = models.CharField(max_length=100, blank=True)
    email = models.EmailField(max_length=150)
    signup_confirmation = models.BooleanField(default=False)

    def __str__(self):
        return self.user.username

@receiver(post_save, sender=User)
def update_profile_signal(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)
    instance.profile.save()
Enter fullscreen mode Exit fullscreen mode

Now, let's create a new module named tokens.py

from django.contrib.auth.tokens import PasswordResetTokenGenerator
from django.utils import six

class AccountActivationTokenGenerator(PasswordResetTokenGenerator):
    def _make_hash_value(self, user, timestamp):
        return (
            six.text_type(user.pk) + six.text_type(timestamp) +
            six.text_type(user.profile.signup_confirmation)
        )

account_activation_token = AccountActivationTokenGenerator()
Enter fullscreen mode Exit fullscreen mode

PasswordResetTokenGenerator is generating a token without persisting it in the database so, we extended it to create a unique token generator to confirm registration or email address. This make use of your project’s SECRET_KEY, so it is a secure and reliable method.

Once user clicked the link, it will no longer be valid.The default value for the PASSWORD_RESET_TIMEOUT_DAYS is 7 days but you can change its value in the settings.py .

Here is the forms.py:

from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User

class SignUpForm(UserCreationForm):
    first_name = forms.CharField(max_length=100, help_text='Last Name')
    last_name = forms.CharField(max_length=100, help_text='Last Name')
    email = forms.EmailField(max_length=150, help_text='Email')


    class Meta:
        model = User
        fields = ('username', 'first_name', 'last_name', 'email', 'password1', 'password2', )
Enter fullscreen mode Exit fullscreen mode

and in views.py we will no longer authenticate the user, instead we will send activation link.

views.py

def signup_view(request):
    if request.method  == 'POST':
        form = SignUpForm(request.POST)
        if form.is_valid():
            user = form.save()
            user.refresh_from_db()
            user.profile.first_name = form.cleaned_data.get('first_name')
            user.profile.last_name = form.cleaned_data.get('last_name')
            user.profile.email = form.cleaned_data.get('email')
            # user can't login until link confirmed
            user.is_active = False
            user.save()
            current_site = get_current_site(request)
            subject = 'Please Activate Your Account'
            # load a template like get_template() 
            # and calls its render() method immediately.
            message = render_to_string('activation_request.html', {
                'user': user,
                'domain': current_site.domain,
                'uid': urlsafe_base64_encode(force_bytes(user.pk)),
                # method will generate a hash value with user related data
                'token': account_activation_token.make_token(user),
            })
            user.email_user(subject, message)
            return redirect('activation_sent')
    else:
        form = SignUpForm()
    return render(request, 'signup.html', {'form': form})
Enter fullscreen mode Exit fullscreen mode

So basically we are generating activation url with user related data and sending it. Note that, we are setting user.is_active = False that means user can't login until he/she confirmed the registration.

Now, create activation_request.html template which will ask from user to confirm the link (This will show up in your console).

{% autoescape off %}
Hi {{ user.username }},

Please click the following link to confirm your registration:

http://{{ domain }}{% url 'activate' uidb64=uid token=token %}
{% endautoescape %}
Enter fullscreen mode Exit fullscreen mode

Check your console:

confirmation-link

Create one more template named activation_sent.html. This will inform user that to check his/her mail to confirm registration

<h3>Activation link sent! Please check your console or mail.</h3>
Enter fullscreen mode Exit fullscreen mode

When user clicked the link, we have to check if the user exists and the token is valid.

def activate(request, uidb64, token):
    try:
        uid = force_text(urlsafe_base64_decode(uidb64))
        user = User.objects.get(pk=uid)
    except (TypeError, ValueError, OverflowError, User.DoesNotExist):
        user = None
    # checking if the user exists, if the token is valid.
    if user is not None and account_activation_token.check_token(user, token):
        # if valid set active true 
        user.is_active = True
        # set signup_confirmation true
        user.profile.signup_confirmation = True
        user.save()
        login(request, user)
        return redirect('home')
    else:
        return render(request, 'activation_invalid.html')
Enter fullscreen mode Exit fullscreen mode

Once registration confirmed, user becomes active and be able to login.

Full code of views.py:

from django.contrib.auth import login, authenticate
from django.shortcuts import render, redirect, get_object_or_404, HttpResponseRedirect
from django.contrib.sites.shortcuts import get_current_site
from django.utils.encoding import force_text
from django.contrib.auth.models import User
from django.db import IntegrityError
from django.utils.http import urlsafe_base64_decode
from django.utils.encoding import force_bytes
from django.utils.http import urlsafe_base64_encode
from .tokens import account_activation_token
from django.template.loader import render_to_string

from .forms import SignUpForm
from .tokens import account_activation_token

def home_view(request):
    return render(request, 'home.html')

def activation_sent_view(request):
    return render(request, 'activation_sent.html')


def activate(request, uidb64, token):
    try:
        uid = force_text(urlsafe_base64_decode(uidb64))
        user = User.objects.get(pk=uid)
    except (TypeError, ValueError, OverflowError, User.DoesNotExist):
        user = None
    # checking if the user exists, if the token is valid.
    if user is not None and account_activation_token.check_token(user, token):
        # if valid set active true 
        user.is_active = True
        # set signup_confirmation true
        user.profile.signup_confirmation = True
        user.save()
        login(request, user)
        return redirect('home')
    else:
        return render(request, 'activation_invalid.html')

def signup_view(request):
    if request.method  == 'POST':
        form = SignUpForm(request.POST)
        if form.is_valid():
            user = form.save()
            user.refresh_from_db()
            user.profile.first_name = form.cleaned_data.get('first_name')
            user.profile.last_name = form.cleaned_data.get('last_name')
            user.profile.email = form.cleaned_data.get('email')
            # user can't login until link confirmed
            user.is_active = False
            user.save()
            current_site = get_current_site(request)
            subject = 'Please Activate Your Account'
            # load a template like get_template() 
            # and calls its render() method immediately.
            message = render_to_string('activation_request.html', {
                'user': user,
                'domain': current_site.domain,
                'uid': urlsafe_base64_encode(force_bytes(user.pk)),
                # method will generate a hash value with user related data
                'token': account_activation_token.make_token(user),
            })
            user.email_user(subject, message)
            return redirect('activation_sent')
    else:
        form = SignUpForm()
    return render(request, 'signup.html', {'form': form})
Enter fullscreen mode Exit fullscreen mode

Finally, let's configure our urls.py:

from django.contrib import admin
from django.urls import path
from django.conf.urls import url
from accounts.views import home_view, signup_view, activation_sent_view, activate

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', home_view, name="home"),
    path('signup/', signup_view, name="signup"),
    path('sent/', activation_sent_view, name="activation_sent"),
    path('activate/<slug:uidb64>/<slug:token>/', activate, name='activate'),
]
Enter fullscreen mode Exit fullscreen mode

I pushed all these projects in my GitHub you can clone which project you want by selecting right branch.

github

GitHub logo raszidzie / django-advanced-signup-tutorial

Create Advanced User Sign Up View in Django | Step-by-Step

django-advanced-signup-tutorial

Create Advanced User Sign Up View in Django | Step-by-Step

Getting Started

This tutorial works on Python 3+ and Django 2+.

Clone the project by selecting right branch and run following commands:

python3 manage.py makemigrations accounts
python3 manage.py migrate
python3 manage.py runserver

Great! In this tutorial we used console to check our link but you can configure a production quality email service to send actual confirmation mail. My next tutorial will cover this topic so make sure you are following me on social media and check Reverse Python for more articles like this.

Instagram
Twitter

Discussion (35)

Collapse
supergoogler profile image
SuperGoogler

Hello coderasha,
I have tried most of the websites where I could look for an answer, but I didn't get any. Since I am new to web development, so not able to debug the issue properly. I have scratched every part of my head with no luck. I hope you would help me.

My website workflow is as below:

1) user sign up and redirect to login screen once registration successful.
2) user login and now he/she sees a form, where he/she needs to fill in mandatory fields
3) save and then either click on "profile" link(in the navbar) to see the profile data, or "save" button will redirect to the profile page automatically.

what's working:

  • Registration page
  • login page
  • user successfully able to fill in the extra information
  • redirect to the logged in user's profile page.
  • Data getting saved in DB.

What's not working:
The profile page that is getting generated for logged in user has the data showing up for default User model, i.e(first_name, last_name, and email). However, the other information like (dob, photo, country, state) etc, is not getting populated on the profile page.

What I have tested already.
I learned that "request.user.model_name" will help to populate the information. So, for that I have to create signals. I have done that as well, but no luck.

Errors:

RelatedObjectDoesNotExist at /profile/
User has no userprofile.
Request Method: GET
Request URL: 127.0.0.1:8000/profile/
Django Version: 3.0.5
Exception Type: RelatedObjectDoesNotExist
Exception Value:

User has no userprofile.
Exception Location: C:\Python38\lib\site-packages\django\db\models\fields\related_descriptors.py in get, line 420
Python Executable: C:\Python38\python.exe
Python Version: 3.8.2
Python Path:

['C:\Users\anshu\djago-project\SkoolSkill',
'C:\Python38\python38.zip',
'C:\Python38\DLLs',
'C:\Python38\lib',
'C:\Python38',
'C:\Python38\lib\site-packages']

Server time: Sun, 3 May 2020 15:48:15 +0000

So, to test further I used "request.user"(at this point signal or no signal, the data comes for those 3 fields). So, as said, only few fields populate the data from DB, but the custom fields doesn't

Below are my django files details:

views.py

from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from .forms import SignUpForm, UserProfileForm
from django.views.decorators.csrf import csrf_exempt

def login_user(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
messages.success(request, f'login success')
return redirect('bolo')
else:
messages.error(request, f'error while login, please try again')
return redirect('login')
else:
return render(request, 'authenticate\login.html', {})

def userprofileview(request): # Authenticated user filling the form to complete the registration
if request.method == 'POST':
form = UserProfileForm(request.POST, request.FILES)
if form.is_valid():
form.save()
messages.success(request, f'Profile has been updated successfully')
return redirect('/profile')
else:
messages.error(request, AssertionError)
else:
form = UserProfileForm()
return render(request, 'authenticate\bolo.html', context={'form': form})

@login_required
def profile_page(request): # Fetching data from DB to show user's complete profile page
form = UserProfileForm()
data = request.user.userprofile
context = {'form': form, 'data': data}
return render(request, 'authenticate\profile.html', context)

urls.py

urlpatterns = [
path('', home, name='home'),
path('contact/', home, name='contact'),
path("login/", login_user, name='login'),
path("logout/", logout_user, name='logout'),
path("register/", register_user, name='register'),
path("bolo/", userprofileview, name='bolo'),
path('profile/', profile_page, name='profile'),
]

models.py

from django.db import models
from django.urls import reverse
from django.contrib.auth.models import User

class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, null=True)
Photo = models.FileField(upload_to='documents/%Y/%m/%d/', null=True)
uploaded_at = models.DateTimeField(auto_now_add=True, null=True)
dob = models.DateField(max_length=20, null=True)
country = models.CharField(max_length=100, null=True)
State = models.CharField(max_length=100, null=True)
District = models.CharField(max_length=100, null=True)
phone = models.CharField(max_length=10, null=True)

def get_absolute_url(self):
    return reverse('profile', kwargs={'id': self.id})
Enter fullscreen mode Exit fullscreen mode

profile.html

        <p>Photo:</p>
        <p><img src =` {{ form_data.image.url }}` width="200" height="200" /></p>
        <p>email:`{{ data.email }}`</p>
        <p>fname:`{{ data.first_name }}`</p>
        <p>lname:`{{ data.last_name }}`</p>
        <p>DOB:`{{ form_data.dob }}`</p>
        <p>Country: `{{ form_data.country }}`</p>
        <p>State: `{{ form_data.State }}`</p>
        <p>District: `{{ form_data.District }}`</p>
Enter fullscreen mode Exit fullscreen mode

signals.py

from django.db.models.signals import post_save
from django.contrib.auth.models import User
from django.dispatch import receiver
from .models import UserProfile
+

@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)

@receiver(post_save, sender=User)
def save_profile(sender, instance, **kwargs):
instance.userprofile.save()

apps.py

from django.apps import AppConfig

class AuthenticationConfig(AppConfig):
name = 'AUTHENTICATION'

def ready(self):
    import AUTHENTICATION.signals
Enter fullscreen mode Exit fullscreen mode

I will be very grateful to you if you could help me out.
Thank you

Collapse
coderasha profile image
codepylot Author

Hey! Sorry for late answer. It seems your queryset is not correct. Can you please change

data = request.user.userprofile

to

data = UserProfile.objects.filter(user=request.user)

and finally, update your profile.html:

        <p>Photo:</p>
        <p><img src =`{{ data.image.url }}` width="200" height="200" /></p>
        <p>email:`{{ data.email }}`</p>
        <p>fname:`{{ data.first_name }}`</p>
        <p>lname:`{{ data.last_name }}`</p>
        <p>DOB:`{{ data.dob }}`</p>
        <p>Country: `{{ data.country }}`</p>
        <p>State: `{{ data.State }}`</p>
        <p>District: `{{ data.District }}`</p>
Collapse
supergoogler profile image
SuperGoogler

Hi,

Thank you for your reply. I followed your instructions, but now no data is getting populated at all. Just the field names are showing up. I have attached the screenshot.
Please suggest

Regards,
Amitesh

Thread Thread
coderasha profile image
codepylot Author

Try this one:

from django.shortcuts import render, redirect, get_object_or_404
data = get_object_or_404(UserProfile, user=request.user)

Btw I can't see any screenshots but I think it should work now

Thread Thread
supergoogler profile image
SuperGoogler

Not working, and the strangest part is that the registration, and login is getting successful. The data is going to the database for User model, but now the data has stopped going for the "UserProfile" model to the DB. Before, though the data was not showing up on the web page but the data was going the DB. Below is the ORM query output

User.objects.all()
, , , , , ]>

UserProfile.objects.all()


I really appreciate your effort, and hope we rectify the issue soon. If you are comfortable, I can share my project as a compressed file with you if you would like to test in your environment.
Below is what I see on the web page:

email: email@gmail.com
fname: sam
lname: Sahay
DOB:
Country:
State:
District:

As you could see, first three fields are populating data, but rest not.

Amitesh

Thread Thread
supergoogler profile image
SuperGoogler

Please disregard the previous reply. My apologies. The data is showing up in the database for User model as well as the UserProfile model. I will keep you posted over the latest suggestion by you. There is some issues with the routes . I need to fix that before I see the profile page.

Thank you again.
Amitesh

Thread Thread
supergoogler profile image
SuperGoogler

Hi,

Ok, so there has been some progress. I followed you instructions as well as I modified the function that is responsible to let the authenticated users fill in the form. Below are the two functions that is now modified.

def userprofileview(request): # Authenticated user filling the form to complete the registration
if request.method == 'POST':
form = UserProfileForm(request.POST, request.FILES)
if form.is_valid():
pr = UserProfile()
pr.user = User.objects.get(id=request.user.id)
# pr.first_name = form.cleaned_data['first_name']
# pr.last_name = form.cleaned_data['last_name']
# pr.email = form.cleaned_data['email']
pr.dob = form.cleaned_data['dob']
pr.country = form.cleaned_data['country']
pr.State = form.cleaned_data['State']
pr.District = form.cleaned_data['District']
pr.phone = form.cleaned_data['phone']
pr.save()
messages.success(request, f'Profile has been updated successfully')
return redirect('/profile')
else:
messages.error(request, AssertionError)
else:
form = UserProfileForm()
return render(request, 'authenticate\bolo.html', context={'form': form})

@login_required
def profile_page(request): # Fetching data from DB to show user's complete profile page
data = get_object_or_404(UserProfile, user=request.user)
print('data=', data)
context = {'data': data}
return render(request, 'authenticate\profile.html', context)

1)As you could see in the "userprofileview" view, I have used the form.cleaned_data[] for all the form fields.

2) In the "profile_page", I have used your suggestion.

The change in the webpage is that, now I could see data for all the fields from the custom model UserProfile. However, now the fname, lname, and email is not populating the data.

email:
fname:
lname:
DOB:May 4, 2020
Country: India
State: Mahrashtra
District: Pune

So, I tried the form.cleaned_data() over the first_name, last_name and email. However, it didn't work.
Please suggest,

Thank you
amitesh

Collapse
kynamd profile image
KyNam Doan

Hello CoderAsha,

Great tutorial format by the way, quite easy to follow.

On my local machine, activation works correctly using my gmail account (EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend').

Email is sent, clicking the link activates the user and sets the signup_confirmation bool value to True and the user may now login.

However, once I push it to my live google VM, it no longer works and gives me the error:
SMTPAuthenticationError at /accounts/signup/
(534, b'5.7.14 \n5.7.14 Please log in via your web browser and then try again.\n5.7.14 Learn more at\n5.7.14 support.google.com/mail/answer/78754 a6sm50520455pgg.25 - gsmtp')

Do you have any idea about this?

Thank you!

Collapse
coderasha profile image
codepylot Author

Hi, I am glad you liked the tutorial. Google blocks sign-in attempts from apps which do not use modern security standard. You can however, turn on/off this safety feature by going to the link below:

google.com/settings/security/lesss...

let me know if it worked for you

Collapse
kynamd profile image
KyNam Doan

I just turned this off and it worked. Thanks!

Collapse
irfanharunk profile image
irfan harun

Hi there,

I just downloaded the code from github and i keep getting the following error :
cannot import name 'six' from 'django.utils'.

Please help me resolve the issue. Thanks

Collapse
sree profile image
Sreejith Muralidharan

If you are using Django3,

pip install six

add six to the settings.py INSTALLED_APPS and migrate.

from django.contrib.auth.tokens import PasswordResetTokenGenerator
from six import text_type

class AccountActivationTokenGenerator(PasswordResetTokenGenerator):
    def _make_hash_value(self, user, timestamp):
        return (
            text_type(user.pk) + text_type(timestamp) +
            text_type(user.profile.signup_confirmation)
        )

account_activation_token = AccountActivationTokenGenerator()
Enter fullscreen mode Exit fullscreen mode
Collapse
khoding profile image
Julien

hey this doesn't work for me... you say add six to settings.py, do you mean like this ?

INSTALLED_APPS = [
    ...
    'django.contrib.staticfiles',
    'six',
]
Enter fullscreen mode Exit fullscreen mode

Because I always get "Name 'six' is not defined"
And then what do I have to migrate ?

Thread Thread
sree profile image
Sreejith Muralidharan

That’s right. Can you try pip freeze and check, six was installed correctly?

Thread Thread
khoding profile image
Julien

I managed to fix it after a few tries, so it's good now :)

Collapse
jhoanmartinez profile image
Jhoan Martinez Silva

Worked great, adding to setting.py, huge thanks

Collapse
coderasha profile image
codepylot Author

Hey! That's removed in Django 3.0. django-cors-headers supports Django up until 2.1 right now. So, try to use six library instead of

django.utils.six
Collapse
sopulu497 profile image
Sopulu Nwafor

Awesome post!
Is it possible to modify the UserCreationForm to to include an imagefield so the user uploads an image an image when they are first registering and if they don't then just use the default image

Collapse
skipastyyyy profile image
skipastyyyy

yea u can

Collapse
msshahata profile image
Shahata

Thank you for this effort @conderasha
I have question, What if I don't use django form in signup stage? how can I insert in two models simultaneously (User & User_Profile)?? In django form I can use (.save(commit = false)). what can I do if I don't use form???

Collapse
sirneij profile image
John Idogun

I have a Django application I have implemented this registration flow for but the flow has recently been changed.

The new flow requires that when a user registers, a verification email should be sent and after he/she verifies, a notification email should be sent to the admin, but he/she shouldn't be able to login until the admin approves it followed by a notification email.

How can I achieve this without using libraries/apps such as Django-registration-redux and Django-allauth? Please, include working snippets. I

Collapse
me24git profile image
me24-git

Hello Sir,

Great tutorial, clean and simple very easy to follow.

Sir can i use it to make an API.

If not then what will be the best way to do so?

Collapse
dilipsa profile image
Dilipsa

A little bit confussion ,where the condition is to check user is verified? Only boolean field enough?

Can I implement same concept to login for phone number otp verified user sir?

Thank you gor your great idea.

Collapse
cspatgithub profile image
Cephas Patterson • Edited

Hello, I am a student in Ghana.

I'm really grateful and appreciate this tutorial of yours.

This tutorial has been very useful.
When are you going to release the tutorial on how to "configure a production quality email service to send actual confirmation mail".
Really looking forward to that tutorial.

Thank you.

Collapse
emmanuelcode profile image
Emmanuel-code

Hello,this is very easy and easy to understand,

Please how do I display the profile in views and templates????
I did a lot but still can't
Please help

Collapse
cavinblake profile image
cavinblake

Sir, can you tell me how to verify a profile with something like id card or driving license in django

Collapse
alimp5 profile image
alimp5

Thanks a lot :X
a great step by step tutorial....

Collapse
gurpreet78371 profile image
gurpreet78371

how will you add bio at the time of signUp?
Actually I want to create Profile along with User creation.

Collapse
nhantruong2712 profile image
Nhânđz

Hi coderasha, Can you write a post about Advance Login? Thank you !

Collapse
mickilyon profile image
Michael Lyon

Thank you for this post. It really helped me but I’m stuck on this error:

check_token() missing 1 required positional argument: 'token‘

Collapse
jaweherbensalah profile image
Jaweher Ben Salah

thank you som much this is so helpfull

Collapse
shaphel profile image
Shaphel

Hi coderasha, I couldn't see the user input in the database, please help. I'm new to django and web development

Collapse
sourabh9 profile image
Sourabh Dev

Hello,
when i use Registration with Profile Model i got an error type Attribute error.
AttributeError: 'User' object has no attribute 'profile'
what is the solution of this error.
i am new in Django

Collapse
billy_de_cartel profile image
Billy Okeyo

I'm having problems with six I have tried using it as a library but still I can't get it to work

Collapse
trabelsi10chaima profile image
trabelsi10chaima

hi this error occured to me

AttributeError: module 'roles.tokens.account_activation_token' has no attribute 'make_token'