Django after submit login info, does not lead to intended detail view page
I don't know what to do here after a few days of trying different ideas. After I submit the the prop login email and password, the page does not do anything. It just says "Invalid password". I am not sure my login view is connected to the sqllite
. I am thinking my mistake is where the login view file, but not sure. I also use chatgpt to see if it can identify where the mistake is, but it didn't come up with anything. If anyone can point me where I need to adjust, would be much appricated. If I go to the address of the http://127.0.0.1:8000/user/2/, then, the page shows correctly. Unfortunately, the codes are long.
Here are all the codes:
views.py:
import random
from django.shortcuts import render
from django.views.generic import (ListView, DetailView)
from django.views.decorators.csrf import csrf_exempt
from .models import CustomUser, Events
from rest_framework.views import APIView
from .serializers import CustomUserSerializer, EventsSerializer
from rest_framework.response import Response
from rest_framework import status
from rest_framework.renderers import TemplateHTMLRenderer
from django.contrib.auth import authenticate, login
from django.contrib import messages
from django.shortcuts import redirect, render
from django.urls import reverse
from .models import CustomUser # Assuming CustomUser is your user model
def index(request):
return render(request, "users_application/index.html", {})
def user_detail(request, id):
user = CustomUser.objects.get(id = id)
events = user.events_set.all()
return render(request, "users_application/user_detail.html", {'user': user})
# Define a view function for the login page
def user_login(request):
if request.method == "POST":
email = request.POST.get('email')
password = request.POST.get('password')
if not CustomUser.objects.filter(email=email).exists():
messages.error(request, 'Invalid Email')
return redirect('login')
user = authenticate(request, username=email, password=password)
if user is None:
messages.error(request, "Invalid Password")
return redirect('login')
else:
login(request, user)
# Redirect to the user's detail page after login
return redirect('user-detail', id=user.id)
return render(request, 'users_application/login.html')
class CustomUserAPIView(APIView):
def get(self, request):
users = CustomUser.objects.all()
serializer = CustomUserSerializer(users, many=True)
return Response(serializer.data)
class CustomUserDetailView(APIView):
renderer_classes = [TemplateHTMLRenderer]
template_name = 'users_application/user_detail.html' # Create this template
def get_object(self, id):
try:
return CustomUser.objects.get(id=id)
except CustomUser.DoesNotExist:
raise Http404
def get(self, request, id=None):
if id:
user = self.get_object(id)
serializer = CustomUserSerializer(user)
return Response({'user': serializer.data})
else:
users = CustomUser.objects.all()
serializer = CustomUserSerializer(users, many=True)
return Response({'users': serializer.data})
urls.py
from django.urls import path
from .views import user_detail
from .views import CustomUserAPIView, EventAPIView, CustomUserDetailView, user_login
from . import views
urlpatterns = [
path("", views.index, name="index"), #index is the function name from view.py
#path('users/', views.user_list, name = "users"),
#path('user/<int:id>/', views.user_detail, name = "user_detail"),
path('users/', CustomUserAPIView.as_view(), name='user-list'),
path('user/<int:id>/', CustomUserDetailView.as_view(), name='user-detail'),
path('login/', views.user_login, name='login'),
]
backends.py
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth import get_user_model
class EmailBackend(ModelBackend):
def authenticate(self, request, username=None, password=None, **kwargs):
UserModel = get_user_model()
try:
user = UserModel.objects.get(email=username)
if user.check_password(password):
return user
except UserModel.DoesNotExist:
return None
def get_user(self, user_id):
UserModel = get_user_model()
try:
return UserModel.objects.get(pk=user_id)
except UserModel.DoesNotExist:
return None
settings.py
from pathlib import Path
ALLOWED_HOSTS = ["*"]
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'users_application',
'rest_framework',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'REST_PROJECT.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'REST_PROJECT.wsgi.application'
# Database
# https://docs.djangoproject.com/en/5.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
# Password validation
# https://docs.djangoproject.com/en/5.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/5.0/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/5.0/howto/static-files/
STATIC_URL = 'static/'
# Default primary key field type
# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
AUTH_USER_MODEL = "users_application.CustomUser"
AUTHENTICATION_BACKENDS = ['users_application.backends.EmailBackend', 'django.contrib.auth.backends.ModelBackend']
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login</title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-5">
<!-- Login form -->
<form class="col-6 mx-auto card p-3 shadow-lg" method="post" enctype="multipart/form-data">
<h1 style="text-align: center;"><span style="color: green;">USER LOGIN</span></h1>
{% csrf_token %} <!-- CSRF token for security -->
<!-- Login heading -->
<h3>Login</h3>
<hr>
<!-- Display error/success messages -->
{% if messages %}
<div class="alert alert-primary" role="alert">
{% for message in messages %}
{{ message }}
{% endfor %}
</div>
{% endif %}
<!-- Email input field -->
<div class="form-group">
<label for="exampleInputEmail1">Email</label>
<input type="email" class="form-control" name="email" id="exampleInputEmail1" aria-describedby="emailHelp"
placeholder="Enter email" required>
</div>
<!-- Password input field -->
<div class="form-group">
<label for="exampleInputPassword1">Password</label>
<input type="password" name="password" class="form-control" id="exampleInputPassword1" placeholder="Password" required>
</div>
<!-- Submit button -->
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</body>
</html>
and fanlly, models.py
from django.contrib.auth.models import AbstractUser
from django.contrib.auth.base_user import BaseUserManager
from django.db import models
from django.conf import settings
class CustomUserManager(BaseUserManager):
def create_superuser(self, email, password=None, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
if extra_fields.get('is_staff') is not True:
raise ValueError('Superuser must have is_staff=True')
if extra_fields.get('is_superuser') is not True:
raise ValueError('Superuser must have is_superuser=True')
return self.create_user(email, password, **extra_fields)
def create_user(self, email, password, **extra_fields):
if not email:
raise ValueError('The Email must be set')
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save()
return user
class CustomUser(AbstractUser):
username = None
email = models.EmailField(("email address"), unique=True)
USERNAME_FIELD = "email"
REQUIRED_FIELDS = []
objects = CustomUserManager()
def __str__(self):
return self.email
class Events(models.Model):
TYPES = (
('PRI', 'Rides'),
('CLN', 'Cleaning'),
('CPN', 'Companionship'),
)
#event = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
event = models.ForeignKey(CustomUser, related_name='events', on_delete=models.CASCADE)
date = models.DateTimeField(auto_now_add=True, blank=True, null=True)
category = models.CharField(max_length=50, choices = TYPES)
previous_balance = models.DecimalField(max_digits=7, decimal_places=2, blank=True, null=True)
spent = models.DecimalField(max_digits=7, decimal_places=2, blank=True, null=True)
add = models.DecimalField(max_digits=7, decimal_places=2, blank=True, null=True)
remaining_balance = models.DecimalField(max_digits=7, decimal_places=2, blank=True, null=True)
destination = models.TextField(blank=True)
I see that you have customized some functions but without them being different from the original. If it is in order to understand how they work, it is not bad otherwise it is not necessary, everything you have done in custom django already does it very well, except for the EmailBakend which must personalize the connection mode with email and password. So be careful when you customize or overload functions and classes, make sure that the framework does not already do what you want to modify.
I have run your code and it's work, does your message appear for all user ?