UNC BACS 350

Web Apps with Python/Django

Logo

Lesson 19 - User Authentication

LEARN

User Authentication

User Object

Forms and Logic

Log In

config/urls.py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('accounts/', include('django.contrib.auth.urls')),
    path('', 
        TemplateView.as_view(template_name="templates/theme.html"), 
        name='home'),
]

config/settings.py

LOGIN_REDIRECT_URL = 'home'

templates/registration/login.html

{% extends 'theme.html' %}

{% block content %}
    <h2>Log In</h2>
    <form method="post">
          {% csrf_token %}
          {{ form.as_p }}
          <button type="submit">Log In</button>
    </form>
{% endblock content %}

User status

templates/theme.html

{% if user.is_authenticated %}
    <p>Hi {{ user.username }}!</p>
    <p><a href="{% url 'logout' %}">Log out</a></p>
{% else %}
    <p>You are not logged in.</p>
    <a href="{% url 'login' %}">Log In</a>
{% endif %}

Home Page

templates/theme.html

<html>
  <head>
    <title>User Authentication Demo</title>
    <link href="/static/css/base.css" rel="stylesheet"s>
  </head>
  <body>
      <header>
          <h1><a href="{% url 'home' %}">Home Page</a></h1>

          {% if user.is_authenticated %}
                <p>Hi {{ user.username }}!</p>
                <p><a href="{% url 'logout' %}">Log out</a></p>
          {% else %}
                <p>You are not logged in.</p>
                <a href="{% url 'login' %}">Log In</a>
          {% endif %}
      </header>

      {% block content %}
      {% endblock content %}
  </body>
</html>

Log out

Follow this link to log out

<a href="{% url 'logout' %}">Log out</a>

config/settings.py

LOGOUT_REDIRECT_URL = 'home'

Sign up

Create a new app

$ python manage.py startapp accounts

config/settings.py

INSTALLED_APPS = [..., 'accounts', ]

config/urls.py

urlpatterns = [
    ...
    path('accounts/', include('accounts.urls')),
    ...
]

accounts/urls.py

from django.urls import path
from .views import SignUpView

urlpatterns = [
    path('signup/', SignUpView.as_view(), name='signup'),
]

accounts/views.py

from django.urls import reverse_lazy
from django.views import generic


class SignUpView(generic.CreateView):
    form_class = UserCreationForm
    success_url = reverse_lazy('login')
    template_name = 'registration/signup.html'

templates/sign_up.html

{% extends 'theme.html' %}

{% block content %}
    <h2>Sign Up</h2>
    <form method="post">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit">Sign Up</button>
    </form>
{% endblock content %}

BUILD

Demo of User Accounts

To Do List

Build Users Project

Start Users project

$ cd week7/Users
$ django-admin startproject config .
$ python manage.py startapp accounts

config/settings.py

TEMPLATES = [
    {
        ...
        'DIRS': [BASE_DIR / 'templates'],
        ...
    },
]

LOGIN_REDIRECT_URL = 'home'
LOGOUT_REDIRECT_URL = 'home'
STATIC_URL = '/static/'
STATICFILES_DIRS = [BASE_DIR / "static"]

ALLOWED_HOSTS = ['markseaman.pythonanywhere.com', '127.0.0.1', 'localhost']

INSTALLED_APPS = [
    ...
    'accounts',
]

Test Admin View

$ python manage.py makemigrations
$ python manage.py migrate
$ python manage.py createsuperuser
$ python manage.py runserver
$ browse to 127.0.0.1:8000/admin/
$ git add . && git commit -m "Initial Accounts app"

Django Test

accounts/tests.py

class TestAccountsViews(TestCase):

    def test_home_view(self):
        response = self.client.get('/')
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'theme.html')

    def test_login_view(self):
        response = self.client.get('/accounts/login')
        self.assertEqual(response.status_code, 301)
        self.assertEqual(response.url, '/accounts/login/')

        response = self.client.get('/accounts/login/')
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'theme.html')

    def test_logout_view(self):
        response = self.client.get('/accounts/logout/')
        self.assertEqual(response.status_code, 302)
        self.assertEqual(response.url, '/')

    def test_signup_view(self):
        response = self.client.get('/signup')
        self.assertEqual(response.status_code, 301)
        self.assertEqual(response.url, '/signup/')

        response = self.client.get('/signup/')
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'theme.html')