loading...
Cover image for User Accounts With django-allauth - Building SaaS #41

User Accounts With django-allauth - Building SaaS #41

mblayman profile image Matt Layman Originally published at mattlayman.com ・2 min read

Building SaaS (48 Part Series)

1) Building SaaS with Python and Django #1 2) Reporting scraped data - Building SaaS #2 3 ... 46 3) Multiple Stripe plans - Building SaaS #3 4) Using a background scheduler - Building SaaS #4 5) Updating data models - Building SaaS #5 6) Third party integration modeling - Building SaaS #6 7) Displaying third party data - Building SaaS #7 8) Connecting third party services - Building SaaS #8 9) Finishing third party integration - Building SaaS #9 10) Admin dashboards - Building SaaS #10 11) Semi-automated tasks - Building SaaS #11 12) Automation aides - Building SaaS #12 13) Deploying with Ansible - Building SaaS #13 14) Ansible Cranked to 11 - Building SaaS #14 15) Feature Flags with Django Waffle - Building SaaS #15 16) Feature Flags in Action - Building SaaS #16 17) Canceling Stripe Subscriptions - Building SaaS #17 18) Completing Account Deactivation - Building SaaS #18 19) Pip-tools and App Packaging - Building SaaS #19 20) Making a Shiv App - Building SaaS #20 21) Shiv zipapps and CI - Building SaaS #21 22) Upload to S3 with CircleCI orbs - Building SaaS #22 23) It's Alive! A Django Shiv app - Building SaaS #23 24) In the Guts of a Shiv App - Building SaaS #24 25) It's Permissions, Dummy! - Building SaaS #25 26) Connecting Shiv Apps with Ansible - Building SaaS #26 27) Plug the Shiv App Into Nginx - Building SaaS #27 28) Webpack and collectstatic in CI - Building SaaS #28 29) Add Static Assets to Deployment - Building SaaS #29 30) Ripping Out Node.js - Building SaaS #30 31) Celery In A Shiv App - Building SaaS #31 32) wal-e Postgres Backups - Building SaaS #32 33) Get Out, Git! - Building SaaS #33 34) Bring in the WhiteNoise, Bring in Da Funk - Building SaaS #34 35) Deploying WhiteNoise - Building SaaS #35 36) Configurama - Building SaaS #36 37) Lessons From A Failed SaaS - Building SaaS #37 38) New Project, Who Dis? - Building SaaS #38 39) django-environ and django-debug-toolbar - Building SaaS #39 40) Make A Custom User Model - Building SaaS #40 41) User Accounts With django-allauth - Building SaaS #41 42) Add Styles To Templates - Building SaaS #42 43) Use Tailwind On A Template - Building SaaS #43 44) Fast Forms With UpdateView - Building SaaS #44 45) Templates and Logic - Building SaaS #45 46) A Week At A Time - Building SaaS #46 47) How To Style Sign Up - Building SaaS #47 48) Onboarding - Building SaaS #48

In this episode, we added django-allauth to create accounts that default to email instead of using usernames. We added the package, configured some templates, and created tests.

We continued to look at Will Vincent's django-allauth post on creating user accounts with email and passwords.

django-allauth let's us swap out username and email so that users won't need to create a username, which is the behavior that I want for this service.

In requirements.in, I installed django-allauth:

django-allauth==0.41.0

Then ran pip-compile to create the new requirements.txt and pip to install the actual package.

(venv) $ pip-compile --output-file=requirements.txt requirements.in
(venv) $ pip install -r requirements.txt

After that, we needed to put django-allauth into INSTALLED_APPS.

# project/settings.py
INSTALL_APPS = [
    ...
    "django.contrib.sites",
    "allauth",
    "allauth.account",
    "allauth.socialaccount",
    ...
]

Then I added the settings that Will outlines. These are settings that django-allauth needs to set things up for email-based accounts.

# project/settings.py
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'

AUTHENTICATION_BACKENDS = (
    "django.contrib.auth.backends.ModelBackend",
    "allauth.account.auth_backends.AuthenticationBackend",
)

SITE_ID = 1

ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_SIGNUP_PASSWORD_ENTER_TWICE = False
ACCOUNT_SESSION_REMEMBER = True
ACCOUNT_AUTHENTICATION_METHOD = 'email'
ACCOUNT_UNIQUE_EMAIL = True

Finally, we created some place for the django-allauth views to reside.

# project/urls.py
urlpatterns = [
    path("office/", admin.site.urls),
    path("accounts/", include("allauth.urls")),
]

This gave us enough configuration to see the views in action on the local site.

After that, we created an area for templates at the root of the project. We have to tell Django where the templates directory is.

# project/settings.py
TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [os.path.join(BASE_DIR, "templates")],
        ...
    }
]

Following template configuration, we added some custom templates for login.html and signup.html.

With templates in place, I needed to make a place for user's to land after they logged in. I created a view named app and pointed the settings at that view.

# homeschool/schools/views.py
from django.contrib.auth.decorators import login_required
from django.shortcuts import render


@login_required
def app(request):
    context = {}
    return render(request, "schools/app.html", context)
# project/settings.py
LOGIN_REDIRECT_URL = "app"
ACCOUNT_LOGOUT_REDIRECT_URL = "app"

To finish off the night, I wrote some tests to verify the behavior of my new view.

# homeschool/schools/tests/test_views.py
from django.test import Client, TestCase
from django.urls import reverse

from homeschool.users.tests.factories import UserFactory


class TestApp(TestCase):
    def test_ok(self):
        """The app returns 200 OK for a user."""
        client = Client()
        user = UserFactory()
        client.force_login(user)

        response = client.get(reverse("app"))

        self.assertEqual(response.status_code, 200)

    def test_unauthenticated_access(self):
        """Unauthenticated users are redirected to the login page."""
        client = Client()

        response = client.get(reverse("app"))

        self.assertEqual(response.status_code, 302)
        self.assertIn(reverse("account_login"), response.get("Location"))

These tests prove that an authenticated user can access the site and an unauthenticated user get redirected to the login page.

Next time, we will move on to some of the core models of the project.

This article first appeared on mattlayman.com.

Building SaaS (48 Part Series)

1) Building SaaS with Python and Django #1 2) Reporting scraped data - Building SaaS #2 3 ... 46 3) Multiple Stripe plans - Building SaaS #3 4) Using a background scheduler - Building SaaS #4 5) Updating data models - Building SaaS #5 6) Third party integration modeling - Building SaaS #6 7) Displaying third party data - Building SaaS #7 8) Connecting third party services - Building SaaS #8 9) Finishing third party integration - Building SaaS #9 10) Admin dashboards - Building SaaS #10 11) Semi-automated tasks - Building SaaS #11 12) Automation aides - Building SaaS #12 13) Deploying with Ansible - Building SaaS #13 14) Ansible Cranked to 11 - Building SaaS #14 15) Feature Flags with Django Waffle - Building SaaS #15 16) Feature Flags in Action - Building SaaS #16 17) Canceling Stripe Subscriptions - Building SaaS #17 18) Completing Account Deactivation - Building SaaS #18 19) Pip-tools and App Packaging - Building SaaS #19 20) Making a Shiv App - Building SaaS #20 21) Shiv zipapps and CI - Building SaaS #21 22) Upload to S3 with CircleCI orbs - Building SaaS #22 23) It's Alive! A Django Shiv app - Building SaaS #23 24) In the Guts of a Shiv App - Building SaaS #24 25) It's Permissions, Dummy! - Building SaaS #25 26) Connecting Shiv Apps with Ansible - Building SaaS #26 27) Plug the Shiv App Into Nginx - Building SaaS #27 28) Webpack and collectstatic in CI - Building SaaS #28 29) Add Static Assets to Deployment - Building SaaS #29 30) Ripping Out Node.js - Building SaaS #30 31) Celery In A Shiv App - Building SaaS #31 32) wal-e Postgres Backups - Building SaaS #32 33) Get Out, Git! - Building SaaS #33 34) Bring in the WhiteNoise, Bring in Da Funk - Building SaaS #34 35) Deploying WhiteNoise - Building SaaS #35 36) Configurama - Building SaaS #36 37) Lessons From A Failed SaaS - Building SaaS #37 38) New Project, Who Dis? - Building SaaS #38 39) django-environ and django-debug-toolbar - Building SaaS #39 40) Make A Custom User Model - Building SaaS #40 41) User Accounts With django-allauth - Building SaaS #41 42) Add Styles To Templates - Building SaaS #42 43) Use Tailwind On A Template - Building SaaS #43 44) Fast Forms With UpdateView - Building SaaS #44 45) Templates and Logic - Building SaaS #45 46) A Week At A Time - Building SaaS #46 47) How To Style Sign Up - Building SaaS #47 48) Onboarding - Building SaaS #48

Posted on May 21 by:

mblayman profile

Matt Layman

@mblayman

Matt Layman is a software engineer from Frederick, MD. He is an open source software maintainer and advocate for Python.

Discussion

markdown guide