forms.py isnt applying tailwind styles

I am building an app using django-tailwind. Everything is working and going good. However, I just started creating the login page and when I went to style the inputs via forms.py no style or settings is being applied.

Per django-tailwind instructions I create an app called “theme”. I have a project based templates folder that contains my base.html, my site wide elements (navbar) and registration folder (login.html, register.html, etc)

For the login and registration settings I have an app called “account”.

I have tried many different things, I cant even recall what I have and haven’t tried.

account/views.py

from django.contrib.auth import logout, login
from django.shortcuts import render, redirect
from django.contrib import messages
from .forms import CustomLoginForm
# Create your views here.

def login_view(request):
    form = CustomLoginForm()

    context = {
        'form': form,
    }

    messages.success(request, 'You have successfully logged in.')
    return render(request, 'registration/login.html', context=context)

def logout_view(request):
    logout(request)
    messages.success(request, 'You have successfully logged out.')
    return redirect('home:index')

account/forms.py

from django.contrib.auth.models import User  # Ensure you import the correct User model
from django import forms
from django.forms import TextInput

class CustomLoginForm(forms.Form):
    username = forms.CharField(
        widget=forms.TextInput(attrs={
            'class': 'w-full bg-gray-50 border border-gray-300 text-gray-900 rounded-lg focus:ring-primary-600 focus:border-primary-600 block p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500',
            'placeholder': 'Username'
        }),
        required=True
    )

    password = forms.CharField(
        label='Password',
        widget=forms.PasswordInput(attrs={
            'class': 'w-full bg-gray-50 border border-gray-300 text-gray-900 rounded-lg focus:ring-primary-600 '
                     'focus:border-primary-600 block p-2.5 dark:bg-gray-700 dark:border-gray-600 '
                     'dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500',
            'placeholder': '••••••••'
        }),
        required=True
    )

/templates/registration/login.html

{% extends 'base/base.html' %}
{% load static %}

{% block title %}
	Login
{% endblock title %}

{% block navbar %}
{% endblock navbar %}

{% block content %}
<div class="-my-10">
    <section class="bg-gray-50 dark:bg-gray-800 sm:my-48 md:my-0">
        <div class="flex items-center justify-center px-6 py-8 mx-auto md:h-screen lg:py-0">
            <div class="md:my-10 w-full bg-white rounded-lg shadow dark:border sm:max-w-md xl:p-0 dark:bg-gray-900 dark:border-gray-700">
                <div class="p-6 space-y-4 md:space-y-6 sm:p-8">
                    <div class="flex justify-center py-10">
                        <a href="{% url 'home:index' %}" class="flex items-center">
                            <img class="w-48 md:w-64" src="{% static 'images/logo/logo.png' %}" alt="RateMyMOS logo">
                        </a>
                    </div>
                    <h1 class="text-xl font-bold leading-tight tracking-tight text-gray-900 md:text-2xl dark:text-gray-400 text-center">
                        Log in to your account
                    </h1>
                    <form class="space-y-4 md:space-y-6 text-gray-600" method="post">
                        {% csrf_token %}

                        <div class="w-full">
                            <p class="text-black dark:text-gray-400 pb-2">{{ form.username.label }}</p>
                            {{ form.username }}
                        </div>

                        <div class="w-full">
                            <p class="text-black dark:text-gray-400 pb-2">{{ form.password.label }}</p>
                            {{ form.password }}
                        </div>

                        <div class="flex items-center justify-end">
                            <a href="#" class="text-sm font-medium text-primary-600 hover:underline dark:text-primary-500">Forgot password?</a>
                        </div>

                        <button type="submit" class="w-full text-white bg-primary-600 hover:bg-primary-700 focus:ring-4 focus:outline-none focus:ring-primary-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800">Log in</button>
                        <p class="text-sm font-light text-gray-500 dark:text-gray-400">
                            Don’t have an account yet? <a href="#" class="font-medium text-primary-600 hover:underline dark:text-primary-500">Sign up</a>
                        </p>
                    </form>
                </div>
            </div>
        </div>
    </section>
</div>

{% endblock content %}

I know for a fact, I have restarted the django and tailwind server. I also tried “tailwind build” before and after adding “./**/*.py” to my tailwind.config.js file under “theme/static_src”

I wonder if you’re really getting anything from using Django forms rendering of fields at this point. Writing out the full html seems simpler and easier to maintain than all that?

Thats what I may end up doing but I feel like getting this issue troubleshooted so if I run into on other forms.

Do you think because its a login form, and theres login.html is at project level and forms.py is at account app level?

No if that was a problem you would have much bigger issues.

Can you share the HTML from the browser’s Inspector panel? Just the bit for the form.

The problem might be that the colors you use are not primary Tailwind colors and they need to be defined manually.

Try to add them as custom colors to the tailwind.config.js:

module.exports = {
    content: [
        // Templates in project templates directory
        '../../templates/**/*.html',
        // Templates in app directories
        '../../**/templates/**/*.html',
        // Python files containing Tailwind classes
        '../../**/forms.py'
    ],
    theme: {
        extend: {
            colors: {
                primary: {
                    500: '#6366f1', // Example color - use your desired color
                    600: '#4f46e5',
                    700: '#4338ca',
                    800: '#3730a3',
                }
            }
        },
    },
    plugins: [],
}

I have those in my tailwind.config.js file.

/**
 * This is a minimal config.
 *
 * If you need the full config, get it from here:
 * https://unpkg.com/browse/tailwindcss@latest/stubs/defaultConfig.stub.js
 */

module.exports = {
    content: [
        /**
         * HTML. Paths to Django template files that will contain Tailwind CSS classes.
         */

        /*  Templates within theme app (<tailwind_app_name>/templates), e.g. base.html. */
        '../templates/**/*.html',

        /*
         * Main templates directory of the project (BASE_DIR/templates).
         * Adjust the following line to match your project structure.
         */
        '../../templates/**/*.html',

        /*
         * Templates in other django apps (BASE_DIR/<any_app_name>/templates).
         * Adjust the following line to match your project structure.
         */
        '../../**/templates/**/*.html',

        './**/*.py',

        /**
         * JS: If you use Tailwind CSS in JavaScript, uncomment the following lines and make sure
         * patterns match your project structure.
         */
        /* JS 1: Ignore any JavaScript in node_modules folder. */
        // '!../../**/node_modules',
        /* JS 2: Process all JavaScript files in the project. */
        // '../../**/*.js',

        /**
         * Python: If you use Tailwind CSS classes in Python, uncomment the following line
         * and make sure the pattern below matches your project structure.
         */
        // '../../**/*.py'
    ],
    darkMode: 'class',
      theme: {
        extend: {
          colors: {
            primary: {
              "50": "#eff6ff",
              "100": "#dbeafe",
              "200": "#bfdbfe",
              "300": "#93c5fd",
              "400": "#60a5fa",
              "500": "#3b82f6",
              "600": "#2563eb",
              "700": "#1d4ed8",
              "800": "#1e40af",
              "900": "#1e3a8a",
              "950": "#172554",
            },
          }
        },
        fontFamily: {
          'body': [
            'Inter',
            'ui-sans-serif',
            'system-ui',
            '-apple-system',
            'system-ui',
            'Segoe UI',
            'Roboto',
            'Helvetica Neue',
            'Arial',
            'Noto Sans',
            'sans-serif',
            'Apple Color Emoji',
            'Segoe UI Emoji',
            'Segoe UI Symbol',
            'Noto Color Emoji'
        ],
          'sans': [
            'Inter',
            'ui-sans-serif',
            'system-ui',
            '-apple-system',
            'system-ui',
            'Segoe UI',
            'Roboto',
            'Helvetica Neue',
            'Arial',
            'Noto Sans',
            'sans-serif',
            'Apple Color Emoji',
            'Segoe UI Emoji',
            'Segoe UI Symbol',
            'Noto Color Emoji'
        ]
        }
    },
    plugins: [
        require('@tailwindcss/forms'),
        require('@tailwindcss/typography'),
        require('@tailwindcss/aspect-ratio'),
    ],
}

I see…

  1. Please paste your base.html code.
    Are you sure that you have something like this?
{% load static %}
<!DOCTYPE html>
<html>
<head>
    <!-- ... -->
    <link href="{% static 'css/dist/styles.css' %}" rel="stylesheet"> #OR Whatever the path is
    <!-- ... -->
</head>
  1. Try clearing your browser cache and rebuilding Tailwind

  2. If still you have problems, try this modified version of your form that uses Django’s built-in form rendering with Tailwind classes:

from django.contrib.auth.forms import AuthenticationForm
from django import forms

class CustomLoginForm(AuthenticationForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['username'].widget.attrs.update({
            'class': 'w-full bg-gray-50 border border-gray-300 text-gray-900 rounded-lg focus:ring-primary-600 focus:border-primary-600 block p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500',
            'placeholder': 'Username'
        })
        self.fields['password'].widget.attrs.update({
            'class': 'w-full bg-gray-50 border border-gray-300 text-gray-900 rounded-lg focus:ring-primary-600 focus:border-primary-600 block p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500',
            'placeholder': '••••••••'
        })

I have a flowbite.min.css in project static/css and because I installed django-tailwind I have a theme (app)/css/dist/styles.css the flowbite.min.css is referenced in my base.html file.

I have no experience with flowbite.

Did you try the things I mentioned in my previous post?

Also, is there any other form, view, HTML file that loads normally and utilizes the TailwindCSS?

I implemented it just now and the style applied. However, it won’t let me login now. I’ll trouble shoot that.

You’re not handling the POST request, and you’re showing the success message regardless of whether the login was successful or not.

Try something like this:

def login_view(request):
    if request.method == 'POST':
        form = CustomLoginForm(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 is not None:
                login(request, user)
                messages.success(request, 'You have successfully logged in.')
                return redirect('home:index')  # or wherever you want to redirect after login
            else:
                messages.error(request, 'Invalid username or password.')
    else:
        form = CustomLoginForm()

    return render(request, 'registration/login.html', {'form': form})