[英]Error about Django custom authentication and login?
I create a custom Authentication backends for my login system.我为我的登录系统创建了一个自定义身份验证后端。 Surely, the custom backends works when I try it in python shell.
当然,当我在 python shell 中尝试时,自定义后端可以工作。 However, I got error when I run it in the server.
但是,当我在服务器中运行它时出现错误。 The error says "The following fields do not exist in this model or are m2m fields: last_login".
错误提示“此模型中不存在以下字段或为 m2m 字段:last_login”。 Do I need include the last_login field in customer model or Is there any other solution to solve the problem?
我需要在客户模型中包含 last_login 字段还是有其他解决方案来解决这个问题? Here is my sample code:
这是我的示例代码:
In my models.py
class Customer(models.Model):
yes_or_no = ((True, 'Yes'),(False, 'No'))
male_or_female = ((True,'Male'),(False,'Female'))
name = models.CharField(max_length=100)
email = models.EmailField(max_length=100,blank = False, null = False)
password = models.CharField(max_length=100)
gender = models.BooleanField(default = True, choices = male_or_female)
birthday = models.DateField(default =None,blank = False, null = False)
created = models.DateTimeField(default=datetime.now, blank=True)
_is_active = models.BooleanField(default = False,db_column="is_active")
@property
def is_active(self):
return self._is_active
# how to call setter method, how to pass value ?
@is_active.setter
def is_active(self,value):
self._is_active = value
def __str__(self):
return self.name
In backends.py在后端.py
from .models import Customer
from django.conf import settings
class CustomerAuthBackend(object):
def authenticate(self, name=None, password=None):
try:
user = Customer.objects.get(name=name)
if password == getattr(user,'password'):
# Authentication success by returning the user
user.is_active = True
return user
else:
# Authentication fails if None is returned
return None
except Customer.DoesNotExist:
return None
def get_user(self, user_id):
try:
return Customer.objects.get(pk=user_id)
except Customer.DoesNotExist:
return None
In views.py在views.py中
@login_required(login_url='/dataInfo/login/')
def login_view(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = authenticate(name=username,password=password)
if user is not None:
if user.is_active:
login(request,user)
#redirect to user profile
print "suffcessful login!"
return HttpResponseRedirect('/dataInfo/userprofile')
else:
# return a disable account
return HttpResponse("User acount or password is incorrect")
else:
# Return an 'invalid login' error message.
print "Invalid login details: {0}, {1}".format(username, password)
# redirect to login page
return HttpResponseRedirect('/dataInfo/login')
else:
login_form = LoginForm()
return render_to_response('dataInfo/login.html', {'form': login_form}, context_instance=RequestContext(request))
In setting.py在设置.py
AUTHENTICATION_BACKENDS = ('dataInfo.backends.CustomerAuthBackend', 'django.contrib.auth.backends.ModelBackend',)
This is happening because you are using django's login()
function to log the user in.发生这种情况是因为您正在使用 django 的
login()
函数来登录用户。
Django's login
function emits a signal named user_logged_in
with the user
instance you supplied as argument. Django 的
login
函数发出一个名为user_logged_in
的信号,其中包含您提供的user
实例作为参数。 See login()
source . 请参阅
login()
源。
And this signal is listened in django's contrib.auth.models
.这个信号在 django 的
contrib.auth.models
被监听。 It tries to update a field named last_login
assuming that the user instance you have supplied is a subclass of django's default AbstractUser
model.它尝试更新名为
last_login
的字段,假设您提供的用户实例是 django 默认AbstractUser
模型的子类。
In order to fix this, you can do one of the following things:为了解决这个问题,您可以执行以下操作之一:
login()
function shipped with django and create a custom one.login()
函数并创建一个自定义函数。user_logged_in
signal from update_last_login
receiver.user_logged_in
信号与update_last_login
接收器的连接。 Read how . last_login
to your modellast_login
的字段添加到您的模型中Thanks, I defined a custom login
method as follows to get through this issue in my automated tests in which I by default keep the signals off.谢谢,我定义了一个自定义
login
方法,如下所示,以在我的自动测试中解决这个问题,我默认情况下保持信号关闭。
Here's a working code example.这是一个工作代码示例。
def login(client: Client, user: User) -> None:
"""
Disconnect the update_last_login signal and force_login as `user`
Ref: https://stackoverflow.com/questions/38156681/error-about-django-custom-authentication-and-login
Args:
client: Django Test client instance to be used to login
user: User object to be used to login
"""
user_logged_in.disconnect(receiver=update_last_login)
client.force_login(user=user)
user_logged_in.connect(receiver=update_last_login)
This in turn is used in tests as follows:这反过来又用于测试,如下所示:
class TestSomething(TestCase):
"""
Scenarios to validate:
....
"""
@classmethod
@factory.django.mute_signals(signals.pre_save, signals.post_save)
def setUpTestData(cls):
"""
Helps keep tests execution time under control
"""
cls.client = Client()
cls.content_type = 'application/json'
def test_a_scenario(self):
"""
Scenario details...
"""
login(client=self.client, user=<User object>)
response = self.client.post(...)
...
Hope it helps.希望它有帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.