Аутентификация пользователя при входе в систему с помощью модели и формы Django

Я пытаюсь настроить аутентификацию пользователя на странице входа в систему с помощью форм и сравнения со значением моей базы данных, но это не работает. Я также пытался использовать этот конкретный вопрос User Login Authentication using forms and Django logic для решения моей проблемы, но это не помогло.

Models.py

from django.db import models
from django.contrib.auth.password_validation import validate_password

class student(models.Model):
    
    first_name = models.CharField(max_length=150)
    last_name = models.CharField(max_length=150)
    matric_number = models.CharField(max_length=9)
    email = models.EmailField(max_length=50)
    password1 = models.CharField(max_length=255, validators=[validate_password])
    password2 = models.CharField(max_length=255)

    def __str__(self):
        return (self.matric_number)

Это представление сохраняет информацию о пользователе в базе данных

def student(request):
  if request.method == 'POST':
    form = studentForm(request.POST)

    if form.is_valid():
      sign_up = form.save(commit=False)
      #sign_up.password1 = make_password(form.cleaned_data['password1'])
      #sign_up.password2 = make_password(form.cleaned_data['password2'])
      sign_up.status = 1
      sign_up.save()
      user = form.cleaned_data.get('matric_number')
      messages.success(request, "Account was created for "+str(user))
      return redirect(signin)
  else:
    form = studentForm()
  return render(request, 'Student.html',{
    "form": form
  })

Это вид входа

def signin(request):
  if request.method == 'POST':
    form = LoginForm(request.POST)
    if form.is_valid():
      username = form.cleaned_data.get('username')
      password = form.cleaned_data.get('password')
      try:
        student = student.object.get(username=username, password=password)
        return redirect(files)
      except:
        messages.success(request, "Error")

  else:
    form = LoginForm()
  return render(request, "SignIn.html",{
      "form":form
    })

Это мой form.py

class studentForm(forms.ModelForm):
    class Meta:
        model=student
        fields="__all__"
        widgets={
            'first_name':forms.TextInput(attrs={'placeholder': 'Enter Your First Name'}),
            'last_name':forms.TextInput(attrs={'placeholder': 'Enter Your Last Name'}),
            'matric_number':forms.TextInput(attrs={'placeholder': 'Enter Your Matric Number'}),
            'email':forms.EmailInput(attrs={'placeholder': 'abc@example.com'}),
            'password1':forms.PasswordInput(attrs={'placeholder': 'Enter Your Preferred Password','id':'password'}),
            'password2':forms.PasswordInput(attrs={'placeholder':'Confirm Your Password', 'id':'password1'})
        }

    def clean(self):
        super(studentForm, self).clean()
        password1 = self.cleaned_data.get('password1')
        password2 = self.cleaned_data.get('password2')
        matric_number = self.cleaned_data.get('matric_number')
        email = self.cleaned_data.get('email')

        try:
            if password1 != password2:
                self.errors[''] = self.error_class(["The two password fields must match"])
            elif len(matric_number) != 9:
                self.errors[''] = self.error_class(["You have entered an invalid matric number"])
            elif len(matric_number) == 9:
                matric_number = int(matric_number)
        except ValueError:
            self.errors[''] = self.error_class(["You have entered an invalid matric number"])

        for instance in student.objects.all():
            if instance.matric_number == str(matric_number):
                self.errors[''] = self.error_class(["Matric number already exist"])
            elif instance.email == email:
                self.errors[''] = self.error_class(["E-mail address already exist"])
    
class LoginForm(forms.Form):
    matric_number = forms.CharField(max_length=9, widget=forms.TextInput(attrs={'id': 'username', 'placeholder': 'Enter Your Staff Id Or Matric Number'})) 
    password1 = forms.CharField(max_length=9, widget=forms.PasswordInput(attrs={'id': 'password', 'placeholder':'Enter Your password'}))

Хватит изобретать колесо. Кроме того, имена классов должны быть названы с использованием PascalCase.

Используйте модель AbstractUser:

from django.contrib.auth.models import AbstractUser

class Student(AbstractUser):
    ...

и в вашем основном urls.py:

from django.contrib.auth import views as auth_views

urlpatterns = [
    ...
    path('login/', auth_views.LoginView.as_view(), name='login'),
    ...
]

Это гораздо более быстрый и безопасный способ создания нового пользователя.

Итак, я понял, как решить мою проблему. Используя модель AbstractUser, я смог создать пользовательского пользователя, а затем создать другую модель, в которой я расширил ForeignKey на модель User, что позволило мне привязать каждого пользователя к его профилю.

Вот мой models.py

from django.db import models
from django.contrib.auth.models import AbstractUser


# Create your models here.
class User(AbstractUser):
    pass
    def __str__(self):
        return self.username

class UserProfile(models.Model):
    """
    This is the one for model.py
    """
    username = models.ForeignKey(User, on_delete=models.CASCADE, null=True, default="")
    profile_picture = models.ImageField(blank=True, null=True, default="")
    matricno = models.CharField(max_length=9, default="", primary_key=True)
    email = models.EmailField(default="")
    first_name = models.CharField(max_length=200, default="")
    last_name = models.CharField(max_length=255, default="")

    class Meta:
        verbose_name_plural = "Users Profile"

    def __str__(self):
        return self.first_name+ " "+self.last_name

А вот мой views.py

def signup(request):
    if request.method == "POST":
        form = Signup(request.POST)
        if form.is_valid():
            username = request.POST["username"]
            email = request.POST["email"]
            password = request.POST["password"]
            password2 = request.POST["password2"]

            user = User.objects.create_user(
                username=username,
                password=password,
                email=email,
            )
            user.save()
            login(request, user)
            messages.success(request, "Account Created successfully for " + username)
            return redirect(details)
    else:
        form = Signup()
    return render(request, "accounts/register.html", {"form": form})

def details(request, username):
    user = User.objects.get(username=username)
    form = Details()
    if request.method == "POST":
        form = Details(request.POST, request.FILES)
        if form.is_valid():
            detail = form.save(commit=False)
            detail.username = request.user
            detail.save()
            return redirect(success, pk=detail.pk)
    else:
        form = Details(initial={"matricno":request.user.username})
    return render(request, "details.html", {"form":form})

И наконец, мой forms.py, который я использую при создании формы подписки и проведении валидации

class Signup(forms.Form):
    username = forms.CharField(
        max_length=9,
        widget=forms.TextInput(attrs={"placeholder": "Enter Your Matric Number"}),
    )

    email = forms.EmailField(
        max_length=255,
        widget=forms.EmailInput(attrs={"placeholder": "Enter Your E-mail Address"}),
    )

    password = forms.CharField(
        max_length=255,
        widget=forms.PasswordInput(
            attrs={"placeholder": "Enter Your Password", "id": "password"}
        ),
    )

    password2 = forms.CharField(
        max_length=255,
        widget=forms.PasswordInput(
            attrs={"placeholder": "Confirm Your Password", "id": "password2"}
        ),
    )
    
    def clean(self):
        super(Signup, self).clean()
        password = self.cleaned_data.get("password")
        password2 = self.cleaned_data.get("password2")
        username = self.cleaned_data.get("username")
        email = self.cleaned_data.get("email")

        if password != password2:
            self.errors[""] = self.error_class(["The two password fields must match"])

        for instance in User.objects.all():
            if instance.username == str(username):
                self.errors[""] = self.error_class(["User already exist"])
            elif instance.email == email:
                self.errors[""] = self.error_class(["E-mail already in use"])
            else:
                pass

        return self.cleaned_data
Вернуться на верх