使用Django 1.5进行身份验证

5

我正在测试Django 1.5和自定义用户模型,但是我有一些理解问题。我在我的账户应用程序中创建了一个名为User的类,它看起来像:

class User(AbstractBaseUser):
    email = models.EmailField()
    activation_key = models.CharField(max_length=255)
    is_active = models.BooleanField(default=False)
    is_admin = models.BooleanField(default=False)

    USERNAME_FIELD = 'email'

我可以正确地注册一个用户,该用户存储在我的account_user表中。 现在,我怎么登录? 我已经尝试了

,但是需要更多的信息来帮助您解决这个问题。
def login(request):
    form = AuthenticationForm()
    if request.method == 'POST':
        form = AuthenticationForm(request.POST)
        email =  request.POST['username']
        password = request.POST['password'] 
        user = authenticate(username=email, password=password)
        if user is not None:
            if user.is_active:
                login(user)
            else:
                message = 'disabled account, check validation email'
                return render(
                        request, 
                        'account-login-failed.html', 
                        {'message': message}
                )
    return render(request, 'account-login.html', {'form': form})

但如果用户为None,则会呈现登录表单:( 我的身份验证为什么会返回None? 有任何想法吗?
forms.py
class RegisterForm(forms.ModelForm):
    """ a form to create user"""
    password = forms.CharField(
            label="Password",
            widget=forms.PasswordInput()
    )
    password_confirm = forms.CharField(
            label="Password Repeat",
            widget=forms.PasswordInput()
    )
    class Meta:
        model = User
        exclude = ('last_login', 'activation_key')

    def clean_password_confirm(self):
        password = self.cleaned_data.get("password")
        password_confirm = self.cleaned_data.get("password_confirm")
        if password and password_confirm and password != password_confirm:
            raise forms.ValidationError("Password don't math")
        return password_confirm

    def clean_email(self):
        if User.objects.filter(email__iexact=self.cleaned_data.get("email")):
            raise forms.ValidationError("email already exists")
        return self.cleaned_data['email']

    def save(self):
        user = super(RegisterForm, self).save(commit=False)
        user.password = self.cleaned_data['password']
        user.activation_key = generate_sha1(user.email)
        user.save()

        return user

当您使用新用户调用login()后,您期望发生什么? - Daniel Roseman
这完全是问题所在。你调用登录,然后...什么也没有发生。你只是跳到最后一行,它再次呈现登录表单。如果你想做其他事情,你需要实际编写代码来完成其他任务。 - Daniel Roseman
@DanielRoseman 根据OP的说法,authenticate()返回了None,因此他甚至无法进入login()函数。 - César
@César 不,我不是这样做的,我使用我的RegisterForm创建用户,就像我的帖子更新中所示。实际上我真的不明白管理员的目的是什么 :( - billyJoe
你首先尝试使用if form.is_valid()验证表单数据。如果获取的用户为None,则可能存在输入和POST数据的问题。 - Jingo
显示剩余6条评论
1个回答

9
Django 文档中有一个非常好的使用新自定义用户的示例。
从您的代码中,我唯一看到缺少的是自定义身份验证后端。
我有一个名为auth.py的文件。需要"authenticate"和"get_user"方法。
from models import User as CustomUser

class CustomAuth(object):

    def authenticate(self, username=None, password=None):
        try:
            user = CustomUser.objects.get(email=username)
            if user.check_password(password):
                return user
        except CustomUser.DoesNotExist:
            return None

    def get_user(self, user_id):
        try:
            user = CustomUser.objects.get(pk=user_id)
            if user.is_active:
                return user
            return None
        except CustomUser.DoesNotExist:
            return None

然后在您的设置文件中指定身份验证后端

AUTHENTICATION_BACKENDS = ('apps.accounts.auth.CustomAuth')

1
如果您正在使用AbstractBaseUser,是否有必要创建自定义身份验证后端?我们不能继续使用django.contrib.auth.authenticate中的那个[code]吗?因为它依赖于settings.AUTH_USER_MODEL。我没有看到这个版本与那个版本有任何不同。是吗? - Brian Dant
2
你可能想要继承 ModelBackend 类:class CustomAuth(ModelBackend) - AJJ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接