Home > Back-end >  Login Issue "POST" 200 3689 (Python, Django)
Login Issue "POST" 200 3689 (Python, Django)

Time:11-29

I am quite new to Django and followed a tutorial to create a website. I'm not able to log in to an account. When I log in with any details (correct or incorrect), my 'login' page just reloads and nothing else happens (The expected result is that I go into a different page when I log in correctly)

I am getting "POST /login/ HTTP/1.1" 200 3689 in the terminal.

Here's part of the code:

(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')

Creating an account:

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')

I have an issue with creating an account as well. Whenever I create an account, the data isn't saved anywhere on the database for some reason. So instead, I manually added my details to the DB and tried logging in with those details but still it's not letting me log in.

I also thought the issue could be related to the DB itself (like certain data fields might be missing, I don't think the tutorial said all the data in the DB). Hence, I tried adding some data to it to see if permissions or something would affect anything and help me log in but it did not.

I'm now completely stuck and not sure how to proceed. I don't know if it will help but I have added a picture of the Database here

I appreciate any kind of advice on how I can fix my issue of not being able to log in correctly.

CodePudding user response:

You can Create a User like this. Django uses hashing technique to store users' passwords with some salt. If You are creating a user you have to call set_password method to store the 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()

CodePudding user response:

First of all, there is no better tutorial than the original one, it will help you understand many concepts that are not quite well explained in most. No better place to start and to continue growing by further exploring the documentation.

I must say, there are many flaws in your code and project design. Lets start with the database schema you shared. I can see that you don't have a custom user model, instead you have four user models, three of them to represent groups.

In your views, use the 'snake_case' name convention, it is a good practice. Also, to handle input data and validation Django Forms are the way to do it. Lastly, it is not necessary to have three different templates to render based on the group.

To the code...It is all inside an app called 'core'

First, Create the Custom User Model:

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'

remember to add the model in 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

Create the views using forms and setup the URLs:

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'),
]

Create templates using forms and messages:

login.html

{% extends 'base.html' %}

{% block content %}
    {% if messages %}
    <ul >
        {% for message in messages %}
        <li{% if 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 >
        {% for message in messages %}
        <li{% if 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 >
        {% for message in messages %}
        <li{% if 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 %}
  • Related