Как получить доступ к данным пользователя на всех страницах в django?
После входа в систему я хочу получить доступ к данным пользователя, когда захочу (в частности, в навигационной панели). Я не использовал модель пользователя, предоставленную в django. Я создал свою собственную модель для аутентификации. Моя база данных хранится в mysql на phpmyadmin(Xampp).
AdminUser Modal
class adminUser(models.Model):
username=models.CharField(max_length=50)
firstname=models.CharField(max_length=50)
department=models.CharField(max_length=50)
name=models.CharField(max_length=50)
mail=models.CharField(max_length=50)
id=models.IntegerField(primary_key=True)
password=models.CharField(max_length=200)
class Meta:
db_table="admin_users"
admin_users.py
def login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
if username is not None and password is not None:
user=adminUser.objects.get(username=username)
hashed_password = user.password
is_check = bcrypt.checkpw(password.encode('utf8'),hashed_password.encode('utf8'))
print(is_check)
if is_check==True:
return redirect(reverse('faq_index'))
else:
return render(request,'AdminUsers/login.html')
return render(request,'AdminUsers/login.html')
Во время входа в систему данные пользователя могут быть доступны только функции login, но я хочу получить доступ к данным пользователя на всех страницах для панели навигации, а также узнать, аутентифицирован ли пользователь или нет. Поскольку я не использую модель пользователя в django, я не могу использовать user.is_authenticated(). Как же мне это сделать?
Сначала наследуйте модель пользователя от AbstractBaseUser
. Это даст вам некоторые возможности, такие как is_authenticated
, set_password
и т.д.
Затем определите вашу пользовательскую модель пользователя как AUTH_USER_MODEL
в файле settings.py
После этого django будет относиться к вашему пользовательскому пользователю как к пользователю по умолчанию
models.py
from django.contrib.auth.base_user import AbstractBaseUser
class CustomUser(AbstractBaseUser):
...
settings.py
AUTH_USER_MODEL = 'myapp.MyUser'
Документы в https://docs.djangoproject.com/en/3.2/topics/auth/customizing/
Я рекомендую вам сделать шаг назад и расширить встроенную модель User вместо того, чтобы создавать свою собственную.
Как упомянул @Amin, вы можете расширить класс AbstractBaseUser
для создания пользовательской модели User и переопределить AUTH_USER_MODEL
в settings.py
.
Однако, вы можете легко добавить модель Profile
, которая имеет отношения один-к-одному со встроенной моделью User, которая не требует никаких переопределений (какой метод лучше, я сейчас не знаю, но я использую следующий метод без проблем):
from django.conf import settings
from django.contrib.auth import get_user_model
from django.db import models
UserModel = get_user_model()
class Profile(models.Model):
user = models.OneToOneField(UserModel, on_delete=models.CASCADE)
# add your desired fields here
department=models.CharField(max_length=50)
Затем, в той же папке, где находится ваш models.py
, создайте файл с именем signals.py
и добавьте следующий код:
from django.conf import settings
from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import Profile
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_user_settings(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
Это вызовет создание нового объекта Profile
всякий раз, когда будет создан объект User
.
Затем добавьте следующее в папку apps.py
(предполагается, что название приложения users
... пусть оно совпадает с названием приложения, содержащего вашу модель Profile
):
from django.apps import AppConfig
class UsersConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'users'
def ready(self):
import users.signals
Теперь, после запуска миграций, вы сможете использовать встроенную модель User
и добавлять к ней дополнительные поля по желанию в модели Profile
.
Единственным недостатком является то, что это потребует дополнительной работы, если вы хотите изменить модель User
и модель Profile
на одной странице (т.е. вы не сможете просто указать имя модели в UpdateView
).
Я не помню, где я нашел этот метод. Я полагаю, что он был адаптирован с этой страницы на simpleisbetterthancomplex.com, но я не уверен на 100%.
В любом случае, Django автоматически создает первичный ключ id
для вас, поэтому вам, вероятно, не нужно вручную определять его в вашей модели.