Django 用户认证
内置用户认证
django 的用户分为三类,匿名用户,普通用户,超级用户
普通用户是无法登录admin 后台的的,因此我们的普通视图使用这个用户来管理
超级用户是最高权限,可以登录admin后台,可以使用python manage.py createsuperuser 来创建一个超级用户
内置用户类型
匿名用户.
普通类型
普通用户是无法登录admin 后台的的,因此我们的普通视图使用这个用户来管理
def create_user(self, username, email=None, password=None, **extra_fields): extra_fields.setdefault('is_staff', False) extra_fields.setdefault('is_superuser', False) return self._create_user(username, email, password, **extra_fields)
超级用户
超级用户是最高权限,可以登录admin后台,可以使用python manage.py createsuperuser 来创建一个超级用户
def create_superuser(self, username, email, password, **extra_fields): extra_fields.setdefault('is_staff', True) extra_fields.setdefault('is_superuser', True)
用户认证模式 -1: 用户名
我们在用户注册界面使用的是用户名称
使用内值的form from django.contrib.auth.forms import UserCreationForm
创建对应的模板文件signup.html
<h2>Sign up</h2> <form method="post"> {% csrf_token %} {{ form.as_p }} <button type="submit">Sign up</button> </form>
:views.py
def signup(request): """ 使用用户名来注册 :param request: :return: """ if request.method == 'POST': form = UserCreationForm(request.POST) if form.is_valid(): form.save() username = form.cleaned_data.get('username') raw_password = form.cleaned_data.get('password1') user = authenticate(username=username, password=raw_password) login(request, user) return redirect('article-list') else: form = UserCreationForm() return render(request, 'pre_user/signup.html', {'form': form})
截图如下
用户认证模式2: 有附加字段
在某些特殊情况下我们可能会在用户注册的时候需要输入生日这个样子的字段,但是User 并不包含该字段,因此我们需要扩展User 模型
models.py
class Profile(models.Model): """ 多余字段注册 """ user = models.OneToOneField(User, on_delete=models.CASCADE) bio = models.TextField(max_length=500, blank=True) location = models.CharField(max_length=30, blank=True) birth_date = models.DateField(null=True, blank=True) @receiver(post_save, sender=User) def update_user_profile(sender, instance, created, **kwargs): if created: Profile.objects.create(user=instance) instance.profile.save()
forms.py
class SignUpForm(UserCreationForm): birth_date = forms.DateField(help_text='Required. Format: YYYY-MM-DD') class Meta: model = User fields = ('username', 'birth_date', 'password1', 'password2', )
views.py
django.contrib.auth import login, authenticate
django.shortcuts import render, redirect
pre_user.forms import SignUpForm
signup(request):
if request.method == 'POST':form = SignUpForm(request.POST) if form.is_valid(): user = form.save() user.refresh_from_db() # load the profile instance created by the signal user.profile.birth_date = form.cleaned_data.get('birth_date') user.save() raw_password = form.cleaned_data.get('password1') user = authenticate(username=user.username, password=raw_password) login(request, user) return redirect('article-list')
else:
form = SignUpForm()
return render(request, 'pre_user/signup.html', {'form': form})
4 . 模板文件不需要修改
截图
用户认证模式2: 邮箱注册
这是最常见的用户注册模式
扩展用户创建的forms.py
class SignUpForm(UserCreationForm): """ 使用邮箱注册""" email = forms.EmailField(max_length=254, help_text='Required. Inform a valid email address.') class Meta: model = User fields = ('username', 'email', 'password1', 'password2', )
views.py
(1) 注册视图
def signup(request): if request.method == 'POST': form = SignUpForm(request.POST) if form.is_valid(): user = form.save(commit=False) user.is_active = False user.save() current_site = get_current_site(request) subject = 'Activate Your MySite Account' message = render_to_string('pre_user/account_activation_email.html', { 'user': user, 'domain': current_site.domain, 'uid': urlsafe_base64_encode(force_bytes(user.pk)), 'token': account_activation_token.make_token(user), }) # user.email_user(subject, message) # 给该用户发送邮件 user.email_user(subject=subject, message='message',html_message=message) # 给该用户发送邮件 return redirect('account_activation_sent') # return HttpResponse("邮箱已经发送,请前往验证") else: form = SignUpForm() return render(request, 'pre_user/signup.html', {'form': form})
(2) 用户激活邮箱
def activate(request, uidb64, token): try: uid = force_text(urlsafe_base64_decode(uidb64)) user = User.objects.get(pk=uid) except (TypeError, ValueError, OverflowError, User.DoesNotExist): user = None if user is not None and account_activation_token.check_token(user, token): user.is_active = True user.profile.email_confirmed = True user.save() login(request, user) return redirect('article-list') else: return render(request, 'pre_user/account_activation_invalid.html')
(3) 注册链接
urls.py
urlpatterns = [ url(r'^signup/$', views.signup), url(r'^login/$', auth_views.login, {'template_name': 'pre_user/login.html', 'authentication_form': LoginForm}), url(r'^activate/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', views.activate, name='activate'), url(r'^account_activation_sent/$', views.account_activation_sent, name='account_activation_sent'), ]
(4)模板
account_activation_email.html
{% extends 'pre_user/base.html' %} {% block content %} <div class="container"> <div class="row"> <div class="jumbotron"> {% autoescape off %} Hi {{ user.username }}, Please click on the link below to confirm your registration: http://{{ domain }}{% url 'activate' uidb64=uid token=token %} {% endautoescape %} </div> </div> </div> {% endblock %}
account_activation_sent.html
{% extends 'pre_user/base.html' %} {% block content %} <div class="container"> <div class="row"> <div class="jumbotron"> 邮件已经发送 </div> </div> </div> {% endblock %}
account_activation_invalid.html
{% extends 'pre_user/base.html' %} {% block content %} <div class="container"> <div class="row"> <div class="jumbotron"> 邮件格式不合法 </div> </div> {% endblock %}