Задать вопрос
@nevsherst

Как сделать так, чтобы значение request.user кастомной User-модели сохранялось между страницами?

Есть код:
/project/user/models.py
import datetime
from django.contrib.auth.models import AbstractBaseUser, UserManager, PermissionsMixin
from django.db import models

class MyUserManager(UserManager):
	def create(self, **kwargs):
		user = super().create(**kwargs)
		user.set_password(user.password)
		user.save()
		return user
	def get(self, **kwargs):
		if kwargs.get('email', None) is not None:
			return super().get(email=kwargs['email'])
		return None

class User(AbstractBaseUser, PermissionsMixin):
	username = models.CharField(max_length=40)
	email = models.EmailField(max_length=40, unique=True)
	password = models.TextField()
	USERNAME_FIELD = 'email'
	REQUIRED_FIELDS = ['username', 'password']
	is_active = models.BooleanField(default=True)
	is_staff = models.BooleanField(default=False)
	is_superuser = models.BooleanField(default=False)
	last_login = models.DateTimeField(default=datetime.datetime.now)
	date_joined = models.DateTimeField(default=datetime.datetime.now)
	objects = MyUserManager()

/project/admission/backend.py
from django.contrib.auth.backends import BaseBackend
from user.models import User

class Backend(BaseBackend):
	def authenticate(self, request=None, username=None, email=None, password=None):
		if None in [email, password]:
			return None
		scope = locals()	
		data = {i: eval(i, scope) for i in ['username', 'email', 'password'] if eval(i, scope) is not None}
		try:
			password = data.pop('password')
			user = User.objects.get(**data)
			if not user.check_password(password):
				return None
		except:
			return None
		return user

/project/admission/views.py
from .forms import RegistrationForm
from django.shortcuts import redirect, render
from user.models import User
from django.contrib.auth import login

def registration(request):
	data = {i: request.POST.get(i, None) for i in ['username', 'password', 'email']}
	form = RegistrationForm()
	response = render(request, 'admission/registration.html', context={'form': form})
	if None not in data.values():
		if len(User.objects.filter(email=data['email'])) == 0:
			obj = User.objects.create_user(username=data['username'], email=data['email'], password=data['password'])
			login(request, obj)
			response = redirect('/')
	return response

/project/project/settings.py
AUTH_USER_MODEL = 'user.User'
AUTHENTICATION_BACKENDS = ['admission.backend.Backend']

Суть проблемы заключается в том, что строка login(request, obj) вроде как и логинит пользователя, заполняя request.user, но только до того времени, пока не возвращается response. Потом request.user заполняется анонимным пользователем, несмотря на то, что в куках запись sessionid создается. Нужно ли будет переписывать функцию login(), или проблема кроется в другом?
  • Вопрос задан
  • 320 просмотров
Подписаться 1 Средний Комментировать
Решения вопроса 1
@nevsherst Автор вопроса
Проблема заключалась в том, что бэкенд аутентификации является классом, который реализует два обязательных метода: get_user и authenticate (первый из которых я не прописал). Лично в моем коде я подправил методы модели MyUserManager и, собственно, добавил необходимый метод в Backend:
/project/user/models.py
class MyUserManager(UserManager):
	def create(self, **kwargs):
		user = super().create(**kwargs)
		user.set_password(user.password)
		user.save()
		return user
	def get(self, **kwargs):
		if kwargs.get('email', None) is not None:
			return super().get(email=kwargs['email'])
		elif kwargs.get('id', None) is not None:
			return super().get(id=kwargs['id'])
		return None

/project/admission/backend.py
class Backend:
	def authenticate(self, request=None, username=None, email=None, password=None):
		if None in [email, password]:
			return None
		scope = locals()	
		data = {i: eval(i, scope) for i in ['username', 'email', 'password'] if eval(i, scope) is not None}
		try:
			password = data.pop('password')
			user = User.objects.get(**data)
			if not user.check_password(password):
				return None
		except:
			return None
		return user
	def get_user(self, iden):
		return User.objects.get(id=iden)
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы