Table of Contents

  1. Basic Settings
  2. Basic Login System
  3. CustomUser Model
  4. Actions in Admin for models
  5. Choices type in Models
  6. Messages in Django Templates
  7. Transaction Atomic
  8. Time in IST
  9. Humanize Date and Time

Basic Settings

  1. settings.py in Main App Folder
    # At the start
    import os
    from django.contrib.messages import constants as message_constants
    
    # Replace Original
    TIME_ZONE = 'Asia/Kolkata'
    
    # Under the Static declaration 
    STATICFILES_DIRS = [
        os.path.join(BASE_DIR, "static")
    ]
    
    # At the end
    MESSAGE_TAGS = {
        message_constants.ERROR: 'danger',
    }
  2. Add in Template DIRS settings.py in Main App Folder
    os.path.join(BASE_DIR, "templates")
  3. Add in Installed Apps settings.py in Main App Folder
    'home.apps.HomeConfig'

Basic Login System

  1. import these in views.py file in Home App
    from django.shortcuts import redirect, render, HttpResponse
    from django.contrib.auth import authenticate, login, logout
    from django.contrib import messages
  2. views.py file in Home App
    # Index Handler
    def index(request):
        if request.user.is_anonymous:
            return redirect("/login")
        return render(request, "index.html", {"active": "home"})
                    
    # Login Handler
    def loginUser(request):
        if request.method != "POST":
            return HttpResponse("Invalid Method")
        username = request.POST.get("username")
        password = request.POST.get("password")
        rememberme = request.POST.get("rememberme")
        if not rememberme:
            request.session.set_expiry(0)
        else:
            request.session.set_expiry(86400)
        user = authenticate(username=username, password=password)
        if user is not None:
            login(request, user)
            messages.add_message(request, messages.SUCCESS, 'Login Successfull')
            return redirect("/")
        messages.add_message(request, messages.ERROR, 'Invalid Username or Password')
        return redirect("/login")
    
    # Login View
    def loginView(request):
        if request.user.is_authenticated:
            return redirect("/")
        return render(request, "login.html")
    
    # Logout Handler
    def logoutUser(request):
        logout(request)
        return redirect("/")
    
    # About page, for illustrative purpose only
    def about(request):
        if request.user.is_anonymous:
            return redirect("/login")
        return render(request, "about.html", {"active": "about"})
  3. Add this on top in urls.py in Main App
    from django.conf.urls import include
  4. Add this in urlpatterns in urls.py in Main App
    path('', include('home.urls')),
  5. urls.py in Home App
    from django.urls import path
    from .views import index, loginUser, loginView, logoutUser, about
    
    urlpatterns = [
        path('', index),
        path('login', loginView, name="Login View"),
        path('loginUser', loginUser, name="Login Authenticator"),
        path('logout', logoutUser, name="Logout"),
        path('about', about, name="About"),
    ]
  6. login.html in Templates
    <!doctype html>
    <html lang="en">
    
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="description" content="Login to Examsite by Sai Krishna">
        <meta name="author" content="Sai Krishna">
        <title>Login</title>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
        <link defer rel="stylesheet" href="/static/bootstrap-5.0.1/css/bootstrap.min.css"> 
        <!-- Theme colour -->
        <!--meta name="theme-color" content="#7952b3"-->
    
        <style>
        .bd-placeholder-img {
            font-size: 1.125rem;
            text-anchor: middle;
            -webkit-user-select: none;
            -moz-user-select: none;
            user-select: none;
        }
    
        @media (min-width: 768px) {
            .bd-placeholder-img-lg {
            font-size: 3.5rem;
            }
        }
    
        html, body {
            height: 100%;
        }
    
        body {
            display: flex;
            align-items: center;
            padding-top: 40px;
            padding-bottom: 40px;
            background-color: #f5f5f5;
        }
    
        .form-signin {
            width: 100%;
            max-width: 330px;
            padding: 15px;
            margin: auto;
        }
    
        .form-signin .checkbox {
            font-weight: 400;
        }
    
        .form-signin .form-floating:focus-within {
            z-index: 2;
        }
    
        .form-signin input[type="email"] {
            margin-bottom: -1px;
            border-bottom-right-radius: 0;
            border-bottom-left-radius: 0;
        }
    
        .form-signin input[type="password"] {
            margin-bottom: 10px;
            border-top-left-radius: 0;
            border-top-right-radius: 0;
        }
        </style>
    
    
    </head>
    
    <body class="text-center">
    
        <main class="form-signin">
        <form method="post" action="/loginUser">
            {% csrf_token %}
            <img class="mb-4" src="/static/home/logo.png" alt="Logo" width="72" height="72">
            <h1 class="h3 mb-3 fw-normal">Please sign in</h1>
            {% if messages %}
            {% for message in messages %}
            <div {% if message.tags %} class="alert alert-{{ message.tags }} alert-dismissible fade show" {% endif %}
            role="alert">
            {{ message }}
            <button type="button" class="close py-3" data-dismiss="alert" aria-label="Close">
                <span aria-hidden="true">×</span>
            </button>
            </div>
            {% endfor %}
            {% endif %}
            <div class="form-floating">
            <input type="text" name="username" class="form-control" id="username" placeholder="Username">
            <label for="floatingInput">Username</label>
            </div>
            <div class="form-floating">
            <input type="password" name="password" class="form-control" id="password" placeholder="Password">
            <label for="floatingPassword">Password</label>
            </div>
    
            <div class="checkbox mb-3">
            <label>
                <input type="checkbox" name="rememberme" value="True"> Remember me
            </label>
            </div>
            <button class="w-100 btn btn-lg btn-primary" type="submit">Sign in</button>
            <div class="mt-4">
            New User? <a href="/signup" style="text-decoration: none;">Register Here.</a>
            </div>
            <p class="mt-3 mb-3 text-muted">© 2020–2021</p>
        </form>
        </main>
        <!-- Optional JavaScript -->
        <!-- jQuery first, then Popper.js, then Bootstrap JS -->
        <script src="/static/jquery-3.6.0.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut" crossorigin="anonymous"></script>
        <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script>
        <!-- <script src="/static/bootstrap-5.0.1/js/bootstrap.min.js"></script> -->
    
    </body>
    
    </html>
  7. index.html in Templates
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Title</title>
    </head>
    <body>
        Hello World
    </body>
    </html>

CustomUser Model

  1. models.py in Home
    from django.db import models
    from django.contrib.auth.models import AbstractUser, User
    from django.urls import reverse
    
    # Create your models here.
    
    # Overriding the Default Django Auth User and adding One More Field (user_type)
    class CustomUser(AbstractUser):
        userid = models.IntegerField(primary_key=True, unique=True)
  2. forms.py in Home
    from django import forms
    from django.contrib.auth.forms import UserCreationForm
    from .models import CustomUser
    
    class CustomUserCreationForm(UserCreationForm):
        class Meta(UserCreationForm.Meta):
            model = CustomUser
            fields = "__all__"
  3. admin.py in Home
    from django.contrib import admin
    from django.contrib.auth.admin import UserAdmin
    from django.db import transaction
    from .models import CustomUser
    from .forms import CustomUserCreationForm
    
    # Register your models here.
    
    class CustomUserAdmin(UserAdmin):
        model = CustomUser
        add_form = CustomUserCreationForm
        list_display = ['username', 'email', 'first_name', 'last_name', 'is_staff' #Add more]
        fieldsets = (
            *UserAdmin.fieldsets,
            (
                'User Role', {
                    'fields': ('user_type', 'userid')
                }
            )
        )
        
    admin.site.register(CustomUser, CustomUserAdmin)
  4. settings.py in Main App
    AUTH_USER_MODEL = 'home.CustomUser'
  5. Import in views.py if required in Home
    from django.contrib.auth.hashers import make_password
    from django.db import IntegrityError
  6. Create new user in views.py in Home
    def createNewUser(request):
        if request.method!="POST":
            return HttpResponse("Invalid Method GET")
        data = json.loads(request.body.decode("utf-8"))
        first_name = data["first_name"]
        last_name = data["last_name"]
        email = data["email"]
        username = data["username"]
        password = data["password"]
        try:
            u = CustomUser()
            u.first_name=first_name
            u.last_name=last_name
            u.email=email
            u.username=username
            u.password=make_password(password)
            u.save()
            context = {"message": "User Created Successfully", "status": 200}
        except IntegrityError:
            context = {"message": "Sorry, this Username already exists", "status": 500}
        except Exception as e:
            context = {"message": str(e), "status": 500}
        return HttpResponse(json.dumps(context), content_type="application/json")

Actions in Admin for models

  1. Add these to admin.py after imports
    # Add these to admin.py after imports
    @transaction.atomic
    def custom_action(modeladmin, request, queryset):
        for obj in queryset:
            # Change the obj data here like obj.somefield = something and last obj.save()
    custom_action.short_description = 'Cutsom Action for Models'
  2. Add this to admin.py in the Model Admin
    actions = [ custom_action ]

Choices type in Models

  1. Add these to models.py in required Model
    FIELD_CHOICES = ((1, "Choice 1"), (2, "Choice 2"), (3, "Choice 3"))
    field = models.IntegerField(default=1, choices=FIELD_CHOICES)

Messages in Django Templates

  1. Import messages in views.py where required
    from django.contrib import messages
  2. Add this in the view in which you want messages
    messages.add_message(request, messages.SUCCESS, 'Your message here')
  3. Add these where messages are to be placed in Django Templates
    {% if messages %}
    {% for message in messages %}
    <div {% if message.tags %} class="alert alert-{{ message.tags }} alert-dismissible fade show" {% endif %}
    role="alert">
    {{ message }}
    <button type="button" class="close py-3" data-dismiss="alert" aria-label="Close">
        <span aria-hidden="true">×</span>
    </button>
    </div>
    {% endfor %}
    {% endif %}

Transaction Atomic

  1. Add this in views.py at top
    from django.db import transaction
  2. Use this in views.py where required
    # Transaction Atomic
    @transaction.atomic
    def function_name(request):
        pass

Time in IST

  1. Add this in views.py at top
    from pytz import timezone
  2. Use this where time is required in IST
    datetimeobj.astimezone(timezone('Asia/Kolkata')).strftime('%b. %d, %Y, %I:%M %p')

Humanize Date and Time

  1. Add this in Installed Apps in settings.py
    'django.contrib.humanize'
  2. Use this where humanize filter is required
    {% load humanize %}
    {{ datetimeobject|naturaltime }}