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

Я создал роли пользователей в моем Django приложении и назначил пользователям их роли в интерфейсе администратора, но когда я вхожу в систему и пытаюсь получить доступ к странице ограниченного доступа, используя правильную роль, я либо возвращаюсь на страницу входа в систему, либо получаю ошибку list index out of range, и я очень озадачен, почему это происходит.

Models.py

from pickle import TRUE
from django.db import models
from django.contrib.auth.models import User
from django.template.defaultfilters import slugify
from django.urls import reverse
from django.utils import timezone

    
ROLES = (
    ('0','Researcher'),
    ('1','Clinician'),
    ('2','Superuser'),
    )


class UserProfile(models.Model):
    # This line is required. Links UserProfile to a User model instance.
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    # The additional attributes we wish to include.
    picture = models.ImageField(upload_to='profile_images', default='default/default.jpg', blank=True)
    role = models.CharField(max_length=1000, choices=ROLES, default='0')
    is_active = models.IntegerField(default = 1,
                                   blank = True,
                                    null = True,
                                    help_text ='1->Active, 0->Inactive', 
                                    choices =(
                                    (1, 'Active'), (0, 'Inactive')
                                    ))
    created_on = models.DateTimeField(default = timezone.now)
    updated_on = models.DateTimeField(default = timezone.now,
                                    null = True, 
                                    blank = True
                                    )

Views.py

from django.shortcuts import render, redirect
from django.urls import reverse
from django.http import HttpResponse
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from parasites_app.models import Contact, UserProfile,Category,Photo
from parasites_app.forms import ContactForm
from django.core.mail import send_mail

from django.contrib.auth import REDIRECT_FIELD_NAME
from django.contrib.auth.decorators import user_passes_test

#for the permissions decorators
def find_role(u):
    userprofile = UserProfile.objects.filter(user = u)[0]
    return userprofile.role

#create decorators to dictate permissions
#@clinician_required
def clinician_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url='login'):
    actual_decorator = user_passes_test(
        lambda u: u.is_active and find_role(u) == 'Clinician',
        login_url=login_url,
        redirect_field_name=redirect_field_name
    )
    if function:
        return actual_decorator(function)
    return actual_decorator


@clinician_required
def Clinician(request):
    category = request.GET.get('category')
    if category == None:
        photos = Photo.objects.all()
    else:
        photos = Photo.objects.filter(
            category__name=category)

    categories = Category.objects.all()
    context = {'categories': categories, 'photos': photos}
    return render(request,'parasites_app/Clinician.html',context)

Я думаю, что проблема может быть в find_role(u) == 'Clinician'

Роль, возвращаемая из find_role, является числовым ключом, хранящимся для данного кортежа вариантов. Возможно, find_role можно переписать следующим образом:

def find_role(u):
    userprofile = UserProfile.objects.filter(user = u)[0]
    return userprofile.get_role_display()

Я также могу предложить перенести логику определения того, что пользователь является клиницистом, в модель пользователя. Например, создать метод is_clinician, который возвращает true или false, и использовать его в проверке разрешения, возможно. Просто предложение.

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

Вернуться на верх