Django Admin: customize the auth system
Tags: webdev, programming, tutorial, python
Published: 2024-07-12 13:58:15

Django admin is insanely good for an out-of-the-box lean and clean admin panel; it's not the most "sexy" looking dashboard around but it gets the job done for internal company tools.

If you don't like the look and feel of Django Admin but want to be lazy like me and re-use the auth system to get a basic login/logout starting point, this tut is for you!

## Routes

In your "urls.py" add these to your routes:
```python
from django.urls import path
from myapp.views import (
    login_view,
    logout_view,
)

urlpatterns = [
    ...
    path("accounts/login/", login_view, name="accounts_login"),
    path("accounts/logout/", logout_view, name="accounts_logout"),
]

```

## Controller methods

Now let's handle our login routes in "myapp/views.py":

```python

def login_view(request):
    error = None
    form = LoginForm()

    if request.method == "POST":
        form = LoginForm(request.POST)
        if form.is_valid():
            username = form.cleaned_data["username"]
            password = form.cleaned_data["password"]

            user = authenticate(request, username=username, password=password)
            if user:
                login(request, user)
                if user.is_superuser:
                    return HttpResponseRedirect("/admin/")
                return HttpResponseRedirect("/dashboard")
            else:
                error = "Login failed. Please check your details and try again."
    return render(request, "login.html", {"form": form, "error": error})
```
As is the standard with all Django forms, you need a form object for this login view, so add this to "forms.py"

```python
from django import forms

class LoginForm(forms.Form):
    username = forms.CharField(label="Your username", max_length=100)
    password = forms.CharField(widget=forms.PasswordInput())
```
Handling the logout is as simple as:
```python
def logout_view(request):
    logout(request)
    return HttpResponseRedirect("/accounts/login")
```

## A login template

Now that you have a basic login in place, we need to add our "login.html" form as follows:

```python
<form action="/accounts/login/" method="post" class="login-form">
		{% csrf_token %} 
	<div class="form-group">
		<input type="text" name="username" class="form-control rounded-left" placeholder="Username" required>
	</div>
<div class="form-group d-flex">
	<input type="password" name="password" class="form-control rounded-left" placeholder="Password" required>
</div>

<div class="form-group">
	<button type="submit" class="btn btn-primary rounded submit p-3 px-5">Login</button>
</div>

</form>
```

For readability, I kept the markup stupidly simple, but the essential here is the actual form that captures the user's details and posts to our login route.

## Protecting routes
```python

from django.contrib.auth.decorators import login_required

@login_required
def dashboard(request):
    # access the user's information via request.user
```
You can use this decorator anywhere in your views.py to restrict access to any route you wish.

>💡 Want some of that Next.js Kool-Aid everyone is drinking without having to deal with JS? Try [Django Unicorn](https://www.django-unicorn.com/). It's open-source and super easy to implement.

## Conclusion

Wasn't that such a breeze? Django is a powerful framework, that will make you super productive regardless of how big or small your application is.