[PYTHON] Creating a login screen with Django allauth

Django-allauth

Django-allauth is a package that makes it easy to implement account creation and login functionality in Django.

In this article, the django-allauth template looks great and even runs the test. For information on how to start a project, please refer to Starting a Django Project.

template for allauth

From venv / lib, which has a package for python virtual environment under templates / allauth set in base.py Copy the contents of venv / lib / python3.6 / site-packages / allauth / account / templates to templates / allauth.

base.py


TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            os.path.join(BASE_DIR, 'templates', 'allauth'), #Place to put login template etc.
            os.path.join(BASE_DIR, 'templates'), #Where to put the template
        ],

Regarding django-allauth url

The authentication urls defined in django-allauth are venv /lib/python3.6/site-packages/allauth/account/urls.py It is described in.

*/allauth/account/urls.py


urlpatterns = [
    url(r"^signup/$", views.signup, name="account_signup"),
    url(r"^login/$", views.login, name="account_login"),
    url(r"^logout/$", views.logout, name="account_logout"),
    ...
]

If you want to write a link to logout in the header (HTML), you can write the name set in the above urlpatterns as follows.

<a class="dropdown-item" href="{% url 'account_logout' %}">Log out</a>

Screen design

When changing the html of the screen of django-allauth, the problem is that the field is set in the loop of {% for field in form%} which is the template syntax, so I understand how to set css. It was difficult.

login.html


{% for field in form%}
      <div class="account-form">
        <div class="account-filed">
            {% if forloop.last %}
            <span class="last-field">{{ field }}</span>
              <span class="login-maintain">Stay logged in</span>
            {% else %}
              <span class="non-last-field">{{ field }}</span>
            {% endif %}
        </div>

        <div class="account-helptext">
          {% if field.errors %}
            <p>{{ field.errors.0 }}</p>
          {% endif %}
        </div>
      </div>
    {% endfor%}

As a workaround, first draw in the initial state and check what kind of elements are included in Google verification. Then, you need to enclose filed in span or div and change / add the element or new element.

For example, I can't see the input in login.html above, but it contains the input. Therefore, if you set as follows, the appearance will be reflected.

input {
    border:none;
    font-size: 60%;
    padding-top:25px;
    padding-bottom: 0px;
    border-bottom: 1px solid #ff7700;
    outline: none;
    font: 800;

}

An example of the login screen is as follows.

git : login.html git : account-style.css

![Screenshot 2019-08-17 16.11.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481395/eb462c1d-a74f-ce7b-4c93- 6ae31d557af4.png)

Similarly, git has examples of creating accounts and changing passwords.

test

Here, we will implement the test of account creation, login, and logout functions. First, create a folder for testing in the main app.


mkdir ./main/tests
touch ./main/test/__init__.py
rm ./main/tests.py 

I wrote a test for account creation and login in test_allauth.py. For testing with Django, you can run the test with ./manage.py test in a file format called test_ * .py.

test_allauth.py


from django.test import TestCase
from django.core import mail
from allauth.account.forms import LoginForm, SignupForm
from allauth.utils import get_user_model
from django.contrib import auth
from django.urls import reverse
from unittest.mock import patch
from main import models

class TestSignUp(TestCase):
    def setUp(self):
        self.post_user_data = {
            "username": "username543",
            "email": "[email protected]",
            "password1": "abcabcabc",
            "password2": "abcabcabc",
        }

    def test_user_signup_page_loads_correctly(self):
        response = self.client.get(reverse('account_signup'))
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'account/signup.html')
        self.assertContains(response, 'SIGN UP')
        self.assertIsInstance(
            response.context['form'], SignupForm
        )
        
    def test_user_signup_page_submission_works(self):
        post_data = self.post_user_data 
        response = self.client.post(
            reverse("account_signup"), post_data
        )
        
        #Redirect to home
        self.assertEqual(response.status_code, 302)

        #Check if a user has been added
        self.assertTrue(
            models.User.objects.filter(
                email=self.post_user_data['email']
            ).exists()
        )
        #Is it logged in?
        self.assertTrue(
            auth.get_user(self.client).is_authenticated
        )

    def test_user_login_page_loads_correctly(self):
        response = self.client.get(reverse('account_login'))
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'account/login.html')
        self.assertContains(response, 'LOGIN')
        self.assertIsInstance(
            response.context['form'], LoginForm
        )

    def test_user_login_page_submission_works(self):
        user1 = models.User.objects.create_user(
            self.post_user_data['username'],
            self.post_user_data['email'],
            self.post_user_data['password1']
        )
        user1.save()

        post_data = {
            'login':self.post_user_data['email'],
            'password':self.post_user_data['password1']    
        }

        #Check if a user has been added
        self.assertTrue(
            models.User.objects.filter(
                email=self.post_user_data['email']
            ).exists()
        )

        response = self.client.post(
            reverse("account_login"), post_data
        )

        #Is it logged in?
        self.assertTrue(
            auth.get_user(self.client).is_authenticated
        )
        
        #Redirect to home
        self.assertEqual(response.status_code, 302)

Recommended Posts

Creating a login screen with Django allauth
A story about implementing a login screen with django
Create a Django login screen
Creating a Home screen
Looking back on creating a web service with Django 1
Looking back on creating a web service with Django 2
Transit to the update screen with the Django a tag
Login with django rest framework
(For beginners) Try creating a simple web API with Django
[Python] Create a screen for HTTP status code 403/404/500 with Django
Set up social login with Django
Creating a decision tree with scikit-learn
Creating a Flask server with Docker
Deploy a Django application with Docker
Django Tips-Create a ranking site with Django-
Creating a simple app with flask
Build a web application with Django
Make a filter with a django template
Commands for creating SNS with Django
Create a file uploader with Django
Creating a simple PowerPoint file with Python
A simple RSS reader made with Django
Commands for creating a new django project
Create an update screen with Django Updateview
A note on enabling PostgreSQL with Django
I made a WEB application with Django
Redo everything for the Django login screen
A series of amateur infrastructure engineers touching Django with Docker (2): Creating a model
[Piyopiyokai # 1] Let's play with Lambda: Creating a Lambda function
How to develop a cart app with Django
Start Django in a virtual environment with Pipenv
Internationalization with django
DJango Memo: From the beginning (creating a view)
Procedure for creating a LineBot made with Python
[Python] Build a Django development environment with Docker
Build a Django environment with Vagrant in 5 minutes
Create a dashboard for Network devices with Django!
A memo when creating a python environment with miniconda
Build a Django development environment with Doker Toolbox
Commands for creating a python3 environment with virtualenv
CRUD with Django
Flow of creating a virtual environment with Anaconda
Create a one-file hello world application with django
A simple to-do list created with Python + Django
Configure a module with multiple files in Django
Quickly build a Python Django environment with IntelliJ
Try creating a web application with Vue.js and Django (Mac)-(1) Environment construction, application creation
Try creating a FizzBuzz problem with a shell program
Procedure for creating an application with Django with Pycharm ~ Preparation ~
Create a Todo app with Django REST Framework + Angular
I tried to create a table only with Django
Create a Todo app with the Django REST framework
Problems when creating a csv-json conversion tool with python
DJango Note: From the beginning (creating a view from a template)
Steps from installing Python 3 to creating a Django app
Create a Todo app with Django ③ Create a task list page
Display a screen that requires login to digital signage
A memo about building a Django (Python) application with Docker
Deploy a Django app made with PTVS on Azure
Launch Django on a Docker container with docker-compose up
I tried a simple RPA for login with selenium