I am building a web project with Django to facilitate distribution in case of an earthquake. The user needs to be a member as a Mukhtar or a Helper. The registration system works successfully. But the login part is constantly returning None value even though my login information is absolutely correct.
models.py:
from django.db import models
from django.contrib.auth.models import AbstractUser
from base64 import b32encode
from hashlib import sha1
from random import random
# Create random id
def pkgen():
rude = ('lol',)
bad_pk = True
while bad_pk:
pk = b32encode(sha1(str(random())).digest()).lower()[:24]
bad_pk = False
for rw in rude:
if pk.find(rw) >= 0: bad_pk = True
return pk
# Create your models here.
class User(AbstractUser):
muhtar = models.BooleanField(null=False,default=False)
tc = models.CharField(max_length=11, null=False, unique=True)
address = models.TextField(null=False)
need_help = models.BooleanField(default=False)
date_joined = models.DateTimeField(auto_now_add=True)
USERNAME_FIELD = 'tc' #Uyarı! Bu benzersiz olmasını ister
REQUIRED_FIELDS = ['username']
def __str__(self):
return f"{self.username}"
class sos(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
sos_key = models.CharField(max_length=24, primary_key=True, default=pkgen, unique=True)
address = models.TextField(null=False, unique=False)
def __str__(self):
return f"{self.user}"
views.py:
from django.shortcuts import render, redirect
from .models import User
from django.contrib.auth import authenticate, login, logout
# Create your views here.
def index(request):
return render(request, "harita.html")
def register(request):
if request.method == "POST":
username = request.POST.get("kullaniciadi")
email = request.POST.get("email")
tc = request.POST.get("tc-no")
password = request.POST.get("password")
muhtar = request.POST.get("muhtar-check")
if muhtar == "on":
muhtar = True
else:
muhtar = False
if username == "" or password == "" or tc == "" or email == "":
return render(request, "register.html", {"error": "Lütfen tüm alanları doldurun."})
#elif len(tc) != 11:
# return render(request, "register.html", {"error": "TC kimlik numarası 11 haneli olmalıdır."})
elif User.objects.filter(tc=tc).exists() or User.objects.filter(email=email).exists():
return render(request, "register.html", {"error": "Bu kimlik numarası veya e-posta adresi zaten kullanılıyor."})
else:
user=User.objects.create_user(username=username, email=email, password=password, tc=tc, muhtar=muhtar)
user.save()
return redirect("login")
return render(request, "register.html")
def login(request):
if request.method == "POST":
tc = request.POST.get("tc-no")
password = request.POST.get("password")
email = request.POST.get("email")
if tc == "" or password == "" or email == "":
return render(request, "login.html", {"error": "Lütfen tüm alanları doldurun."})
user = authenticate(request=request, tc=tc, password=password, email=email)
print(user)
if user is not None:
login(request, user)
return redirect("index")
else:
print(f"""
***************
TC: {tc}
Şifre: {password}
E-posta: {email}
***************""")
return render(request, "login.html", {"error": "E-posta, T.C. veya şifre hatalı."})
return render(request, "login.html")
def logoutPage(request):
logout(request)
return render(request, 'logout.html')
def profile(request):
if request.user.is_authenticated == False:
return redirect("register")
else:
user = User.objects.get(tc=request.user.tc)
return render(request, "profile.html", {"user": user})
def sos(request):
if request.user.is_authenticated == False:
return redirect("register")
elif not request.user.muhtar:
return render(request, "harita.html", {"error": "Yardım çağırma yetkiniz yok."})
if request.method == "POST":
malzemeler = request.POST.get("exampleFormControlTextarea1")
if not malzemeler:
return render(request, "sos.html", {"fillError": "Lütfen gerekli alanları doldurun."})
# Kullanıcının adresini ve usernamesini alabilirsiniz, örneğin:
adres = request.user.address
username = request.user.username
# İşlemlerinizi yapabilirsiniz, örneğin bu bilgileri bir veritabanına kaydedebilirsiniz.
# Başarılı bir şekilde işlem yapıldığında kullanıcıya bir mesaj göndermek için
return render(request, "sos.html", {"succmsg": "Yardım çağrınız başarıyla gönderildi."})
return render(request, "sos.html")
login.html:
{% load static %}
<!DOCTYPE html>
<html lang="tr">
<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>Giriş Sayfası</title>
<link rel="stylesheet" href="{% static 'libs/bootstrap.min.css' %}">
<link rel="stylesheet" href="{% static 'register_and_login.css' %}">
<script src="{% static 'libs/jquery.min.js' %}"></script>
</head>
{% block navbar %}
{% include "navbar.html" %}
{% endblock navbar %}
<div class="container">
<div id="brs">
<br><br><br><br>
<!--giriş formu-->
<form id="giris-form" method="POST">
{% csrf_token %}
{% if error %}
<div class="alert alert-danger">{{ error }}</div>
{% endif %}
<h3>Giriş Yap</h3>
<label for="email">Email</label>
<input type="text" id="email" name="email">
<label for="tc-no">T.C. kimlik numarası</label>
<input type="text" id="tc-no" name="tc-no">
<label for="parola">Parola</label>
<input type="password" id="parola" name="password">
<button type="submit" id="giris-yap">Giriş Yap</button>
</form>
</body>
</html>
I’m in a really difficult situation. I need to finish the project urgently and I can’t make any progress because of this problem.
your user model declares ‘username’ as a required field whereas the model does not have such field. self.username
used in the __str__
method is likely to fail because this field does not exist.
I suppose you use django.contrib.auth.backends.ModelBackend
as authentication backend in your settings. If so, the parameters passed to authenticate
method should be username
and password
(not tc
and password
) : this is the backend which will map the username
parameter with the tc
field of yhe model based on USERNAME_FIELD
value. Changing tc=tc
to username=tc
in the call to authenticate
should solve your issue
the first point of view is that the function to register user is very extensive and can be improved in a more optimal way and the second point of view that I observe is in your html, since in the form tag you only have the id and method==“POST” but the action==" corresponding endpoint" is missing since that is the one that points to the endpoint of your url. I would like to see your urls to see if they are correct and also the error that you comment.
Do you know what is the error I have been dealing with for 5 days? On the HTML registration page, I saved the name tag as “parola”, but this is Turkish, but I translated that word into English in request.POST.get(). Since there is no such tag, it returns an empty value. Django encrypts it and saves it to the database. When I enter the real password on the login page, the empty value does not match the hash value and the authenticate function returns None. Dude, I’m an idiot and I’ve been dealing with this for 5 days. I almost quit my software career :D. Thanks!
i am creating django application but while login i am getting null in authentication I am adding my code
model.py
class CustomUserManager(BaseUserManager):
def create_user(self, email, name, password=None, role=‘user’):
if not email:
raise ValueError(‘Users must have an email address’)
if not name:
raise ValueError(‘Users must have a name’)
user = self.model(
email=self.normalize_email(email),
name=name,
role=role,
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, name, password):
user = self.create_user(
email=self.normalize_email(email),
name=name,
password=password,
role='admin', # Set the role to 'admin' for superuser
user.is_admin = True
user.is_staff = True
user.save(using=self._db)
return user
class CustomUser(AbstractBaseUser):
email = models.EmailField(verbose_name=‘email address’, max_length=255, unique=True)
name = models.CharField(max_length=255)
address = models.CharField(max_length=255)
country = models.CharField(max_length=255)
qualifications = models.TextField(blank=True)
skills = models.TextField(blank=True)
exprence = models.IntegerField(max_length=255)
exp_details = models.CharField(max_length=255)
role = models.CharField(max_length=50, default=‘user’) # Add the ‘role’ field
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
objects = CustomUserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['name']
def __str__(self):
return self.email
def has_perm(self, perm, obj=None):
return self.is_admin
def has_module_perms(self, app_label):
return True
forms.py
class SignUpForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput)
confirm_password = forms.CharField(widget=forms.PasswordInput)
qualifications = forms.CharField(widget=forms.TextInput(attrs={‘placeholder’: ‘Enter qualifications as comma-separated values’}), required=False)
skills = forms.CharField(widget=forms.TextInput(attrs={‘placeholder’: ‘Enter skills as comma-separated values’}), required=False)
class Meta:
model = CustomUser
fields = ['email', 'name', 'address', 'country', 'qualifications', 'skills', 'exprence', 'exp_details', 'password', 'confirm_password']
def clean_confirm_password(self):
password = self.cleaned_data.get('password')
confirm_password = self.cleaned_data.get('confirm_password')
if password != confirm_password:
raise forms.ValidationError("Passwords do not match")
return confirm_password
def clean_experience(self):
experience = self.cleaned_data.get('qualifications')
return experience.split(',') if experience else []
def clean_skills(self):
skills = self.cleaned_data.get('skills')
return skills.split(',') if skills else []
def save(self, commit=True):
user = super(SignUpForm, self).save(commit=False)
user.set_password(self.cleaned_data["password"])
# Check if qualifications is a string before splitting
qualifications = self.cleaned_data["qualifications"]
if isinstance(qualifications, str):
user.qualifications = qualifications.split(",") # Convert experience to a list
else:
user.qualifications = qualifications # Use the existing list
# Check if skills is a string before splitting
skills = self.cleaned_data["skills"]
if isinstance(skills, str):
user.skills = skills.split(",") # Convert skills to a list
else:
user.skills = skills # Use the existing list # Convert skills to a list
if commit:
user.save()
return user
class EmailAuthenticationForm(AuthenticationForm):
username = forms.EmailField(label=‘Email’)
class LoginForm(forms.Form):
email = forms.EmailField(label=‘Email’)
password = forms.CharField(label=‘Password’, widget=forms.PasswordInput)
views.py
def signup(request):
if request.method == ‘POST’:
form = SignUpForm(request.POST)
if form.is_valid():
form.save()
return redirect(‘login’) # Redirect to login page after successful signup
else:
form = SignUpForm()
return render(request, ‘signup.html’, {‘form’: form})
from django.contrib.auth import login, authenticate
from django.shortcuts import render, redirect
from .forms import LoginForm
from django.contrib import messages
def custom_login(request):
error_message = None
if request.method == ‘POST’:
form = LoginForm(request.POST)
if form.is_valid():
email = form.cleaned_data[‘email’]
password = form.cleaned_data[‘password’]
print(f"Email: {email}, Password: {password}") # Debug statement
# Authenticate the user
user = authenticate(request, username=email, password=password)
print(f"Authenticated User: {user}") # Debug statement
if user is not None:
# Login the user
login(request, user)
messages.success(request, 'Login successful.')
# Redirect to the home page
return redirect('home')
else:
error_message = 'Invalid email or password.'
else:
error_message = 'Form is not valid.'
else:
form = LoginForm()
return render(request, 'login.html', {'form': form, 'error_message': error_message})
Welcome @Gaurav-Sarswat !
I suggest you open a new topic for your issue here rather than trying to add to this one.
Also note: When posting code here, enclose the code between lines of three backtick - ` characters. This means you’ll have a line of ```, then your code, then another line of ```. This forces the forum software to keep your code properly formatted.