四、Django2.1 搭建多用户的博客网站——注册

96
麦典威
3.5 2019.01.27 17:47* 字数 1284

目录:Django 2.1 从零开始搭建博客网站系列

服务器环境搭建(选学)

小试牛刀——简单的博客网站

庖丁解牛——多用户的博客网站之用户模块

庖丁解牛——多用户的博客网站之文章模块

华丽转身——多用户的博客网站之扩展功能

项目源码下载:https://github.com/jt1024/lehehe

正文:

1、简单的注册

先实现一个简单的注册例子,不用创建数据库,利用原有的数据库,即Django默认的用户数据模型User。

1.1 创建注册表单

编辑./account/forms 增加以下代码

from django.contrib.auth.models import User
class RegistrationForm(forms.ModelForm):
    password = forms.CharField(label="Password", widget=forms.PasswordInput)
    password2 = forms.CharField(label="ConfirmPassword", widget=forms.PasswordInput)

    class Meta:
        model = User
        fields = ("username", "email")

    def clean_password2(self):
        cd = self.cleaned_data
        if cd['password'] != cd['password2']:
            raise forms.ValidationError("两次输入的密码不匹配")
        return cd['password2']

注意:

  • 注册表单继承的是 forms.ModelForm ,区别于登录表单的 forms.Form
  • 如果要将表单中的数据写入数据库表或修改某些记录的值,就让表单类继承 forms.ModelForm
  • 如果提交表单之后,不会对数据库进行修改,则继承 forms.Form

password 和 password2,User数据模型中没有这两个字段,在这里我们新增这两个字段,如果原数据模型中有这两个字段,则可覆盖。这就是继承 forms.ModelForm 的原因。

fields = ("username", "email") 表示注册表单中使用了User数据模型中的 username 和 email 字段。

clean_ +属性名称 命名方式所创建的方法,会在调用表单实例对象的 is_valid()方法时被执行。

1.2 编写注册的视图函数

在 ./account/views.py 新增 register 方法

from .forms import RegistrationForm

def user_register(request):
    if request.method == "POST":
        user_form = RegistrationForm(request.POST)
        if user_form.is_valid():
            new_user = user_form.save(commit=False)
            new_user.set_password(user_form.cleaned_data['password'])
            new_user.save()
            return HttpResponse("注册成功!")
        else:
            return HttpResponse("抱歉,你不能注册")
    else:
        user_form = RegistrationForm()
        return render(request, "account/register.html", {"form": user_form})

user_form.is_valid() 会触发 forms 中的 clean_password2 函数
user_form.save(commit=False) 仅生成一个数据对象,不会保存到数据库表

1.3 编写注册的模板

创建 ./templates/account/register.html

{% extends "base.html" %}
{% load staticfiles %}
{% block title %}register user{% endblock %}

{% block content %}
<div class="row text-center vertical-middle-sm">
    <h1>Register</h1>
    <p>If you are a user, <strong><a href="{% url 'account:user_login' %}">Login</a> </strong>,please</p>
    <p>or register.</p>
    <form class="form-horizontal" action="." method="post">{% csrf_token %}
        <div class="form-group">
            <label for="{{ form.username.id_for_label }}" class="col-md-5 control-label">Username</label>
            <div class="col-md-6 text-left">{{ form.username }}</div>
        </div>

        <div class="form-group">
            <label for="{{ form.email.id_for_label }}" class="col-md-5 control-label"> Email</label>
            <div class="col-md-6 text-left">{{ form.email }}</div>
        </div>

        <div class="form-group">
            <label for="{{ form.password.id_for_label }}" class="col-md-5 control-label">Password</label>
            <div class="col-md-6 text-left">{{ form.password }}</div>
        </div>

        <div class="form-group">
            <label for="{{ form.password.id_for_label }}" class="col-md-5 control-label"> Confirm Password</label>
            <div class="col-md-6 text-left">{{ form.password2 }}</div>
        </div>

        <input type="submit" class="btn btn-primary btn-lg" value="REGISTER">
    </form>
</div>
{% endblock %}

1.4 在url 中注册

在 ./account/urls.py 增加下面代码

path(r'register/', views.user_register, name='user_register'),

1.5 测试效果

运行Django,访问 http://127.0.0.1:8000/account/register/

注册.png

2、增加注册内容

Django的User数据模型中还有用户姓氏、名字等字段,如果要增加还可以在表单的内部类 fields 的值中继续增加,比如fields = ("first_name", "last_name")
但是,如果要增加一个User数据模型中没有的字段呢?下面我们就来实现。

2.1 创建新的数据模型

在 ./account/models.py 中增加 UserProfile

from django.db import models
from django.contrib.auth.models import User


class UserProfile(models.Model):
    user = models.OneToOneField(User, unique=True, on_delete=models.CASCADE)
    birth = models.DateField(blank=True, null=True)
    phone = models.CharField(max_length=20, null=True)

    def __str__(self):
        return 'user {}'.format(self.user.username)

执行如下命令迁移数据

python manage.py make migrations
python manage.py migrate

![(https://upload-images.jianshu.io/upload_images/2255795-5cee4e2cbd2e146b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

查看数据库,已经生成了数据表account_userprofile


account_userprofile.png

2.2 修改注册的视图函数

修改./account/views.py 中的 user_register 方法

from .forms import UserProfileForm

def user_register(request):
    if request.method == "POST":
        user_form = RegistrationForm(request.POST)
        userprofile_form = UserProfileForm(request.POST)
        if user_form.is_valid() * userprofile_form.is_valid():
            new_user = user_form.save(commit=False)
            new_user.set_password(user_form.cleaned_data['password'])
            new_user.save()
            new_profile = userprofile_form.save(commit=False)
            new_profile.user = new_user
            new_profile.save()
            return HttpResponse("注册成功!")
        else:
            return HttpResponse("抱歉,你不能注册")
    else:
        user_form = RegistrationForm()
        userprofile_form = UserProfileForm()
        return render(request, "account/register.html", {"form": user_form, "profile": userprofile_form})

2.3 修改注册的模板

修改 ./templates/account/register.html

{% extends "base.html" %}
{% load staticfiles %}
{% block title %}register user{% endblock %}

{% block content %}
<div class="row text-center vertical-middle-sm">
    <h1>Register</h1>
    <p>If you are a user, <strong><a href="{% url 'account:user_login' %}">Login</a> </strong>,please</p>
    <p>or register.</p>
    <form class="form-horizontal" action="." method="post">{% csrf_token %}
        <div class="form-group">
            <label for="{{ form.username.id_for_label }}" class="col-md-5 control-label">Username</label>
            <div class="col-md-6 text-left">{{ form.username }}</div>
        </div>

        <div class="form-group">
            <label for="{{ form.email.id_for_label }}" class="col-md-5 control-label"> Email</label>
            <div class="col-md-6 text-left">{{ form.email }}</div>
        </div>

        <div class="form-group">
            <label for="{{ form.password.id_for_label }}" class="col-md-5 control-label">Password</label>
            <div class="col-md-6 text-left">{{ form.password }}</div>
        </div>

        <div class="form-group">
            <label for="{{ form.password.id_for_label }}" class="col-md-5 control-label"> Confirm Password</label>
            <div class="col-md-6 text-left">{{ form.password2 }}</div>
        </div>
        <div class="form-group">
            <label for="{{ profile.birth.id_for_label }}" class="col-md-5 control-label"> Birth Date</label>
            <div class="col-md-6 text-left">{{ profile.birth }}</div>
        </div>

        <div class="form-group">
            <label for="{{ profile.phone.id_for_label }}" class="col-md-5 control-label">Phone</label>
            <div class="col-md-6 text-left">{{ profile.phone }}</div>
        </div>

        <input type="submit" class="btn btn-primary btn-lg" value="REGISTER">
    </form>
</div>
{% endblock %}

2.4 测试效果

运行Django,访问 http://127.0.0.1:8000/account/register/

新注册页面.png

3、管理新增的注册内容

我们新注册的用户能不能在超级管理员后台的界面中管理呢?当然能!

修改 ./account/admin.py

from django.contrib import admin
from .models import UserProfile


class UserProfileAdmin(admin.ModelAdmin):
    list_display = ('user', 'birth', 'phone')
    list_filter = ('phone',)


admin.site.register(UserProfile, UserProfileAdmin)

访问http://127.0.0.1:8000/admin/ 登录后可见页面如下图:

超级管理员后台.png

点击User profile 栏目看看效果

Gupao