如何在登录状态下从Django模板访问自定义用户值?

时间:2015-09-09 16:39:11

标签: python django django-templates django-users

我正在尝试从模板访问用户但是 它在打印{{ user }}{{ request.user }}时显示匿名用户。

我想在网站的标题中设置名称,但始终将名称设为空。请在下面的代码段中找到:

class LoginFormView(View):
    form_class = UserLoginForm
    user_model=get_user_model()
    template_name='account/login.html'

    def get(self,request,*args,**kwargs):
        form=self.form_class
        return render(request, self.template_name, {'form':form})

    def post(self,request,*args,**kwargs):
        email = request.POST['email']
        password = request.POST['password']
        user = authenticate(email=email, password=password)
        if user is not None:
            if user.is_active:
                login(request, user)
                return HttpResponseRedirect(reverse('home'))
        else:
            messages.error(request, 'Please enter correct email and password!')
            return HttpResponseRedirect(request.META.get('HTTP_REFERER','/'))

自定义用户模型:

class UserManager(BaseUserManager):
    def create_user(self, email, password=None, **kwargs):
        if not email:
            raise ValueError('Users must have a valid email address.')

        user = self.model(
            email=self.normalize_email(email), full_name=kwargs.get('full_name')
        )

        user.set_password(password)
        user.save()

        return user

    def create_superuser(self, email, password, **kwargs):
        user = self.create_user(email, password, **kwargs)
        user.is_admin = True
        user.save()

        return user

class User(AbstractBaseUser):
    email = models.EmailField(unique=True)
    username = models.CharField(max_length=40, unique=True, null=True)
    full_name = models.CharField(max_length=50, blank=False)
    phone = models.CharField(max_length=20, unique=True, null=True)
    about = models.CharField(max_length=255, blank=True)
    type = models.CharField(max_length=1, default='U')
    is_active = models.BooleanField(default=True)
    date_joined = models.DateTimeField(auto_now_add=True)

    objects = UserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['full_name']

    def __unicode__(self):
        return self.email

    def get_full_name(self):
        return self.full_name

    def get_short_name(self):
        return self.full_name

2 个答案:

答案 0 :(得分:0)

Django中的默认身份验证后端是'django.contrib.auth.backends.ModelBackend',它使用usernamepassword进行身份验证。 (link to the Docs)

如果您使用此身份验证后端,则您的视图未成功验证用户,这将导致返回AnonymousUser的实例,该实例将永远不会为None。因此,您的视图将永远不会返回错误消息。

要使用email字段进行身份验证,您需要编写自定义后端(您可以在Google上找到示例)或安装提供此后端的多个应用之一。

答案 1 :(得分:0)

您正尝试使用email进行身份验证,但默认身份验证后端不允许我们通过email进行身份验证。

来自authenticate()函数的文档:

  

默认情况下,它以关键字参数的形式获取凭据   配置为usernamepassword,并返回User   对象,如果密码对给定的username有效。

因此,我们需要实施自己的电子邮件身份验证后端。

您可以执行以下操作:

步骤1在设置中替换自定义用户模型:

由于我们不会使用Django的默认User模型进行身份验证,因此我们需要在MyUser中定义自定义settings.py模型。在项目设置中将MyUser指定为AUTH_USER_MODEL

AUTH_USER_MODEL = 'myapp.MyUser'

步骤2编写自定义电子邮件身份验证后端的逻辑:

要编写我们自己的身份验证后端,我们需要实现至少两种方法,即get_user(user_id)authenticate(**credentials)

from django.contrib.auth import get_user_model
from django.contrib.auth.models import check_password

class MyEmailBackend(object):
    """
    Custom Email Backend to perform authentication via email
    """
    def authenticate(self, username=None, password=None):
        my_user_model = get_user_model()
        try:
            user = my_user_model.objects.get(email=username)
            if user.check_password(password):
                return user # return user on valid credentials
        except my_user_model.DoesNotExist:
            return None # return None if custom user model does not exist 
        except:
            return None # return None in case of other exceptions

    def get_user(self, user_id):
        my_user_model = get_user_model()
        try:
            return my_user_model.objects.get(pk=user_id)
        except my_user_model.DoesNotExist:
            return None

步骤3在设置中指定自定义身份验证后端:

编写自定义身份验证后端后,请在AUTHENTICATION_BACKENDS设置中指定此身份验证后端。

AUTHENTICATION_BACKENDS = (
    'my_app.backends.MyEmailBackend', # our custom authentication backend
    )