Вход в систему Выдача "POST" 200 3689 (Python, Django)

Я совсем новичок в Django и следовал учебнику по созданию сайта. Я не могу войти в учетную запись. Когда я вхожу в систему с любыми данными (правильными или неправильными), моя страница "входа" просто перезагружается и больше ничего не происходит (ожидаемый результат - я перехожу на другую страницу, когда я вхожу правильно)

Я получаю "POST /login/ HTTP/1.1" 200 3689 в терминале.

Вот часть кода:

(views.py)

def loginpage(request):
    error = ""
    page = ""
    if request.method == 'POST':
        u = request.POST['email']
        p = request.POST['password']
        user = authenticate(request,username=u,password=p)
        try:
            if user is not None:
                login(request,user)
                error = "no"
                g = request.user.groups.all()[0].name
                if g == 'Doctor':
                    page = 'doctor'
                    d = {'error': error, 'page':page}
                    return render(request,'doctorhome.html',d)
                elif g == 'Receptionist':
                    page = 'reception'
                    d = {'error': error, 'page':page}
                    return render(request,'receptionhome.html',d)
                elif g == 'Patient':
                    page = 'patient'
                    d = {'error': error, 'page':page}
                    return render(request,'patienthome.html',d)
            else:
                error = "yes"
        except Exception as e:
            error = "yes"
            #print(e)
            #raise e
    return render(request,'login.html')

Создание учетной записи:

def createaccountpage(request):
    error = ""
    user="none"
    if request.method == 'POST':
        name = request.POST['name']
        email = request.POST['email']
        password = request.POST['password']
        repeatpassword = request.POST['repeatpassword']
        gender = request.POST['gender']
        phonenumber = request.POST['phonenumber']
        address = request.POST['address']
        birthdate = request.POST['dateofbirth']
        bloodgroup = request.POST['bloodgroup']
        try:
            if password == repeatpassword:
                Patient.objects.create(name=name,email=email,password=password,gender=gender,phonenumber=phonenumber,address=address,birthdate=birthdate,bloodgroup=bloodgroup)
                user = User.objects.create_user(name=name,email=email,password=password,username=email)
                pat_group = Group.objects.get(name='Patient')
                pat_group.user.set.add(user)
                user.save()
                error = "no"
            else:
                error = "yes"
        except Exception as e:
            error = "yes"
            print("Erorr:",e)
    d = {'error' : error}
    #print(error)
    return render(request,'createaccount.html',d)
    #return render(request,'createaccount.html')

У меня тоже есть проблема с созданием учетной записи. Когда я создаю учетную запись, данные по какой-то причине не сохраняются в базе данных. Поэтому вместо этого я вручную добавил свои данные в БД и попробовал войти в систему с этими данными, но все равно это не позволяет мне войти.

Я также подумал, что проблема может быть связана с самой БД (например, некоторые поля данных могут отсутствовать, я не думаю, что в учебнике указаны все данные в БД). Поэтому я попробовал добавить в нее некоторые данные, чтобы посмотреть, повлияют ли разрешения или что-то еще на что-то и помогут ли мне войти в систему, но этого не произошло.

Теперь я полностью застрял и не уверен, как действовать дальше. Не знаю, поможет ли это, но я добавил изображение базы данных здесь

Я признателен за любой совет о том, как я могу решить проблему, связанную с невозможностью правильного входа в систему.

Создать пользователя можно следующим образом. Django использует технику хэширования для хранения паролей пользователей с некоторой солью. Если вы создаете пользователя, вы должны вызвать метод set_password для хранения пароля.

from django.contrib.auth.models import User

user = User()
user.username = request.POST.get('username')
user.set_password(request.POST.get('password'))
user.save()

Прежде всего, нет лучшего учебника, чем оригинальный, он поможет вам понять многие концепции, которые не совсем хорошо объяснены в большинстве. Нет лучшего места, чтобы начать и продолжать расти, изучая документацию.

Должен сказать, что в вашем коде и дизайне проекта есть много недостатков. Начнем со схемы базы данных, которой вы поделились. Я вижу, что у вас нет пользовательской модели, вместо этого у вас есть четыре пользовательские модели, три из которых представляют группы.

В своих представлениях используйте соглашение об именах 'snake_case', это хорошая практика. Также, для обработки входных данных и валидации Django Forms - это то, что нужно. Наконец, нет необходимости иметь три разных шаблона для рендеринга в зависимости от группы.

К коду... Все находится внутри приложения под названием 'core'

Сначала, Создайте пользовательскую модель пользователя:

models.py

from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin

# Create your models here.
GENDER_CHOICES = [
    ('F', 'Female'),
    ('M', 'Male'),
]
BLOOD_GROUP_CHOICES = [
    ('A', 'A'),
    ('B', 'B'),
    ('O', 'O'),
    ('AB', 'AB'),
]

class UserManager(BaseUserManager):
    def create_user(self, email, password=None, **kwargs):
        if not email:
            raise ValueError('Users must have an email address')

        user = self.model(email=self.normalize_email(email), **kwargs)
        user.set_password(password)
        user.save(using=self._db)
        return user 

    def create_superuser(self, email, password=None):
        user = self.create_user(email, password=password)
        user.is_staff = True
        user.is_superuser = True
        user.save(using=self._db)
        return user

class User(AbstractBaseUser, PermissionsMixin):    
    email = models.CharField(max_length=128, unique=True)
    name = models.CharField(max_length=128)
    gender = models.CharField(max_length=10, choices=GENDER_CHOICES)
    phone_number = models.CharField(max_length=128, blank=True)
    address = models.CharField(max_length=128)
    birth_date = models.DateField()
    blood_group = models.CharField(max_length=2, choices=BLOOD_GROUP_CHOICES)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=True)

    objects = UserManager()
    
    USERNAME_FIELD  = 'email'

не забудьте добавить модель в settings.py:

AUTH_USER_MODEL = 'core.User'

forms.py

from django import forms
from django.core.exceptions import ValidationError
from datetime import datetime
from django.contrib.auth import get_user_model

GENDER_CHOICES = [
    ('F', 'Female'),
    ('M', 'Male'),
]
BLOOD_GROUP_CHOICES = [
    ('A', 'A'),
    ('B', 'B'),
    ('O', 'O'),
    ('AB', 'AB'),
]

class UserRegisterForm(forms.ModelForm):        
    password = forms.CharField(label='Password', widget=forms.PasswordInput)
    password_confirmation = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)

    class Meta:
        model = get_user_model()
        fields = ('email', 'name', 'gender', 'phone_number', 'address', 'birth_date', 'blood_group')

    def clean_password_confirmation(self):
        # Check that the two password entries match
        password1 = self.cleaned_data.get("password")
        password2 = self.cleaned_data.get("password_confirmation")
        if password1 and password2 and password1 != password2:
            raise ValidationError("Passwords don't match")
        return password2
    
    def save(self, commit=True):
        # Save the provided password in hashed format
        user = super().save(commit=False)
        user.set_password(self.cleaned_data["password"])
        user.last_login = datetime.now()
        if commit:
            user.save()
        return user

class UserSignInForm(forms.Form):
    email = forms.EmailField(required=True)
    password = forms.CharField(widget=forms.PasswordInput())

    def save(self, commit=True):
        # Save the provided password in hashed format
        user = super().save(commit=False)
        user.last_login = datetime.now()
        if commit:
            user.save()
        return user

Создайте представления с помощью форм и настройте URL:

views.py

from django.shortcuts import render, redirect
from django.contrib import messages
from django.contrib.auth import authenticate, login, logout

from core.forms import UserRegisterForm, UserSignInForm

# Create your views here.
def register(request):
    if request.method == 'POST':
        form = UserRegisterForm(request.POST)
        if form.is_valid():
            form.save()
            messages.success(request, 'Successful registration')
            return redirect('/user/index/')
        else:
            messages.error(request, 'Please fill the fields correctly')
    else:
        form = UserRegisterForm()

    context = {
        'form': form
    }

    return render(request, 'register.html', context)

def user_login(request):
    if request.method == 'POST':
        form = UserSignInForm(request.POST)
        if form.is_valid():
            email = form.cleaned_data['email']
            password = form.cleaned_data['password']
            user = authenticate(request, email=email, password=password)
            if user is not None:
                login(request, user)
                qs = user.groups.values_list('name',flat = True)
                groups = l_as_list = list(qs)
                messages.success(request, 'Successfull login')
                return render(request, 'index.html', {'groups': groups})
            else:
                messages.error(request, 'User not found')
    else:
        form = UserSignInForm()

    context = {
        'form': form
    }
    return render(request, 'login.html', context)

def user_logout(request):
    logout(request)
    return redirect('/user/login/')

def index(request):
    return render(request, 'index.html', {})

urls.py

from django.urls import path
from core import views

app_name = 'core'

urlpatterns = [
    path('index/', views.index, name='index'),
    path('register/', views.register, name='user-register'),
    path('login/', views.user_login, name='user-login'),
    path('logout/', views.user_logout, name='user-logout'),
]

Создайте шаблоны, используя формы и сообщения:

login.html

{% extends 'base.html' %}

{% block content %}
    {% if messages %}
    <ul class="messages">
        {% for message in messages %}
        <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
        {% endfor %}
    </ul>
    {% endif %}

    <form method="POST" action="{% url 'core:user-login' %}">
        {% csrf_token %}
        <table>
            {{ form }}
        </table>
        <input type="submit" value="Submit">
    </form>
{% endblock %}

register.html

{% extends 'base.html' %}

{% block content %}
    {% if messages %}
    <ul class="messages">
        {% for message in messages %}
        <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
        {% endfor %}
    </ul>
    {% endif %}

    <form method="post" action="{% url 'core:user-register' %}">
        {% csrf_token %}
        <table>
            {{ form }}
        </table>
        <button type="submit">Register</button>
    </form>
{% endblock %}

index.html

{% extends 'base.html' %}

{% block content %}
    {% if messages %}
    <ul class="messages">
        {% for message in messages %}
        <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
        {% endfor %}
    </ul>
    {% endif %}

    {% if 'doctor' in groups %}
        <p>I am a doctor</p>
    {% elif 'patient' in groups %}
        <p>I am a patient</p>
    {% elif 'receptionist' in groups %}
        <p>I am a recepcionist</p>
    {% endif %}
    <a href="{% url 'core:user-logout' %}">Logout</a>
{% endblock %}
Вернуться на верх