Django入门日记 Day3

邮差的信 提交于 2020-02-06 09:07:37

用户注册

I. 初始化一个Django App

命令行中cd到项目文件夹,然后:

>python manage.py startapp users

setteings.py中注册新的应用。在INSTALLED_APPS列表中加入以下项:

    'users.apps.UsersConfig',

urls.py中为新应用添加路径。添加如下代码:

from users import views as user_views
urlpatterns = [
    path('register/', user_views.register, name='register'),
]

II. views.py

Django 的UserCreationForm方法中有用户注册的初始化表单布局(但不包括提交按钮),无需自定义,这里将其赋给变量form
render()方法返回渲染后的HttpResponse对象并将表单变量传入register.html。(在users --> templates --> users -->下新建一个register.html

from django.shortcuts import render
from django.contrib.auth.forms import UserCreationForm

def register(request):
	form = UserCreationForm()
    return render(request, 'users/register.html', {'form': form})

III. register.html

  1. 同样继承base.html的布局。
  2. 两种最常用的 HTTP 方法:GET 和 POST。GET - 从指定的资源请求数据。POST - 向指定的资源提交要被处理的数据。这里要向服务器提交用户注册信息,因此要用到POST方法。
  3. 在用到了POST方法的form表单的html模板中需要在<form>元素中添加csrf_token
    <form method="post">{% csrf_token %}
    
    Django文档对CSRF的解释:

    Cross Site Request Forgery protection
    The CSRF middleware and template tag provides easy-to-use protection against Cross Site Request Forgeries.

register.html

{% extends "blog/base.html" %}
{% block content %}

<div class="content-section">
    <form method="POST">
        {% csrf_token %}
        <fieldset class="form-group">
            <legend class="border-bottom ml-0">Join Today !</legend>
            {{ form }}
        </fieldset>
        <div class="form-group">
            <button class="btn btn-outline-info" type="submit">Sign Up</button>
        </div>
    </form>
    <div class="border-top pt-3">
        <small class="text-muted">
            已经有一个账号了?<a class="ml-2" href="#">Sign In</a>
        </small>
    </div>
</div>

{% endblock content %}

为了美化样式,可将{{ form }}修改为{{ form.as_p }},意为将表单分段显示;或者使用crsipy包,在后面会介绍。

IV. 添加注册成功的页面响应

views.py中,

  1. 添加代码,使收到了POST方法的request时,将数据通过UserCreationForm()方法存入变量form,否则使 form为空。

  2. 如果输入数据有效,则通过cleaned_data_get()方法获取用户名(在注册成功通知时引用)。

  3. 导入Django的messages框架,使用messages.sucess方法发送消息。
    常用的messsages方法如下:

    messages.debug(request, '%s SQL statements were executed.' % count)
    messages.info(request, 'Three credits remain in your account.')
    messages.success(request, 'Profile details updated.')
    messages.warning(request, 'Your account expires in three days.')
    messages.error(request, 'Document deleted.')
    

    Message tags有五种:debug, info, success, warning, error。

  4. 导入Django的redirect模块,在注册成功后通过redirect() 方法转到blog-home页面。

base.html中为注册成功消息添加布局:如果messages变量非空,则依次显示每条消息。通过引用messages.tags决定alert 的bootstrap样式。
代码如下:
views.py

from django.shortcuts import render, redirect
from django.contrib.auth.forms import UserCreationForm
from django.contrib import messages

def register(request):
    if request.method == 'POST':
        form = UserCreationForm(request.POST)
        if form.is_valid():
            form.save()
            username = form.cleaned_data.get('username')
            messages.success(request, f'Account created for { username } !')
            return redirect('blog-home')
    else:
        form = UserCreationForm()

    return render(request, 'users/register.html', {'form': form})

base.html:

			<div class="col-md-8">
                {% if messages %}
	                {% for message in messages %}
		                <div class="alert alert-{{ message.tags }}">
		                    {{ message }}
		                </div>
	                {% endfor %}
                {% endif %}
                {% block content %}{% endblock %}
            </div>

V. 保存新用户到服务器

如果用户提交表单有效,则执行form.save()
views.py中改动后代码片段如下:

		if form.is_valid():
            form.save()
            username = form.cleaned_data.get('username')
            messages.success(request, f'Account created for { username } !')
            return redirect('blog-home')

VI. 在注册表单中新建邮箱域

此后,新用户注册后可被保存到服务器,在admin页面中可以查看到。
但其缺少Email信息,因为默认的UserCreationForm()方法中不包含EmailField,可通过自定义一个继承了UserCreationForm方法的新方法,并在此基础上加入EmailField

  1. 在user目录下新建forms.py文件
  2. 导入Django的 formsUserUserCreationForm框架
  3. 定义类UserRegisterForm,继承UserCreationForm方法,并定义类Meta, 这里也不是很懂,待解决。
  4. views.py中导入UserRegisterForm方法并用此方法替换UserCreationForm

代码如下:
forms.py

from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
	
class UserRegisterForm(UserCreationForm)
	email = forms.EmailField()
	
	class Meta:
		model = User
	    fields = ['username','email','password1','password2']

views.py

from django.shortcuts import render, redirect
from django.contrib import messages
from .forms import UserRegisterForm


def register(request):
    if request.method == 'POST':
        form = UserRegisterForm(request.POST)
        if form.is_valid():
            form.save()
            username = form.cleaned_data.get('username')
            messages.success(request, f'Account created for { username } !')
            return redirect('blog-home')
    else:
        form = UserRegisterForm()

    return render(request, 'users/register.html', {'form': form})

VII. 用免费的第三方Django应用crispy美化注册界面

  1. 下载crispy包:pip install django-crispy-forms

  2. settings.py中:INSTALLED_APPS中添加'crispy_forms'项;并在文件最后添加:

    CRISPY_TEMPLATE_PACK = 'bootstrap4'
    

    使crispy使用Bootsrap4的风格(默认为Bootsrap2)。

  3. register.html中,{% load crispy_forms_tags %}, 并使用crispy过滤注册界面表单:{{ form|crispy }}

register.html最终代码:

{% extends "blog/base.html" %}
{% load crispy_forms_tags %}
{% block content %}

<div class="content-section">
    <form method="POST">
        {% csrf_token %}
        <fieldset class="form-group">
            <legend class="border-bottom ml-0">Join Today !</legend>
            {{ form|crispy }}
        </fieldset>
        <div class="form-group">
            <button class="btn btn-outline-info" type="submit">Sign Up</button>
        </div>
    </form>
    <div class="border-top pt-3">
        <small class="text-muted">
            已经有一个账号了?<a class="ml-2" href="#">Sign In</a>
        </small>
    </div>
</div>

{% endblock content %}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!