本篇是在完成用户登录登出,密码修改功能后,扩展用户注册功能。
关于用户登录、注销、更改密码和重置密码。请查看
Django身份验证初试-CSDN博客
Django登录注销视图-CSDN博客
Django密码修改和重置视图-CSDN博客
用户注册
创建一个表单,让用户输入用户名、真实姓名和密码。
编辑位于account应用程序目录中的forms.py文件
from django.contrib.auth.models import User
class UserRegistrationForm(forms.ModelForm):
password = forms.CharField(label='Passowrd',widget=forms.PasswordInput)
password2 = forms.CharField(label='Repeat passowrd',widget=forms.PasswordInput)
class Meta:
model = User
fields = ('username','first_name','email')
def clean_password2(self):
cd = self.cleaned_data
if cd['password'] != cd['password2']:
raise forms.ValidationError("Passwords don't match.")
return cd['password2']
- 表单中包含username,first_name,email字段,这些字段讲根据它们对应的模型进行验证。如果用户填写了一个已经存在的用户名,将得到一个验证错误。因为username是一个用unique=True定义的字段。
- 添加password和password2两个字段,用来确认密码。
- 定义了一个clean_password2方法,用于对照第一个密码检查第二个密码,如果密码不匹配,则不让表单验证。这个检查是在调用is_valid方法时完成的。
Django可以为任何表单字段提供clean_()方法,清楚特定字段的值或引发表单验证错误。表单还包括一个通用的clean()方法来验证整个表单,这对于验证相互依赖的字段非常有用。
Django还提供了一个UserCreationForm表单,它位于Django .contrib.auth.forms中,和刚才创建的表单非常相似。
编辑account应用程序的views.py文件
from .forms import EmailPostForm,CommentForm,SearchForm,UserRegistrationForm
def register(reque服务器托管网st):
if request.method == 'POST':
user_form = UserRegistrationForm(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()
template = "account/register_done.html"
context = {'new_user':new_user}
return render(request,template,context)
else:
user_form = UserRegistrationForm()
template = "account/register.html"
context = {'user_form':user_form}
return render(request,template,context)
这里没有保存用户输入的原始密码,而是使用处理加密的用户模型的set_password()方法进行保存,以保证安全。
编辑account应用的urls.py文件,添加如下URL模式:
path('register/',views.register,name='register'),
在account/ template目录下创建一个新模板,命名为register.html,并使其看起来如下:
{% extends "base.html" %}
{% block title %}Create an account{% endblock %}
{% block服务器托管网 content %}
Create an account
Please, sign up using the following form:
{{ user_form.as_p }}
{% csrf_token %}
{% endblock %}
在同一目录下添加一个模板文件,并将其命名register_done.html。将以下代码添加到其中:
{% extends "base.html" %}
{% block title %}Welcome{% endblock %}
{% block content %}
Welcome {{ new_user.first_name }}!
Your account has been successfully created. Now you can
log in.
{% endblock %}
用户模型扩展
编辑account应用程序的models.py文件
from django.db import models
from django.conf import settings
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL,on_delete=models.CASCADE)
date_of_birth = models.DateField(blank=True, null=True)
photo = models.ImageField(upload_to='users/%Y/%m/%d',blank=True)
def __str__(self):
return 'Profile for user {}'.format(self.user.username)
为了保持代码的泛型,请使用get_user_model()方法检索用户模型和AUTH_USER_MODEL设置,以便在定义模型与用户模型的关系时引用它,而不是直接引用auth用户模型。
- 用户一对一字段允许您将配置文件与用户关联。on_delete参数使用CASCADE,这样当用户被删除时,它的相关配置文件也会被删除。
- 照片字段是一个ImageField字段。您需要安装Pillow库来处理图像。
在shell中运行以下命令安装Pillow:
python -m pip install pillow
为了让Django在开发服务器上为用户上传的媒体文件提供服务,在项目的settings.py文件中添加以下设置:
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
- MEDIA_URL是为用户上传的媒体文件提供服务的基本URL,
- MEDIA_ROOT是媒体文件所在的本地路径。
- Django动态地构建相对于项目路径的路径,以使代码更加通用。
编辑项目的主urls.py文件,修改代码如下:
from django.conf import settings
from django.conf.urls.static import static
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Django开发服务器将负责在开发过程中提供媒体文件(也就是DEBUG设置为True时)。
static()辅助函数适合于开发,但不适合生产使用。永远不要在生产环境中使用Django提供静态文件。
编辑account应用程序的admin.py文件,并在管理站点中注册Profile模型,如下所示:
from django.contrib import admin
from .models import Profile
@admin.register(Profile)
class ProfileAdmin(admin.ModelAdmin):
list_display = ['user','date_of_birth','photo']
让用户在网站上编辑自己的个人资料。
将以下导入和模型表单添加到account应用程序的forms.py文件中:
class UserEditForm(forms.ModelForm):
class Meta:
model = User
fields = ('first_name','last_name','email')
class ProfileEditForm(forms.ModelForm):
class Meta:
model = Profile
- UserEditForm:允许用户编辑自己的名字、姓氏和电子邮件,这些都是Django内置用户模型的属性。
- ProfileEditForm:这将允许用户编辑我们保存在自定义概要模型中的概要数据。用户将能够编辑自己的出生日期,并上传照片作为个人资料。
编辑account应用程序的views.py文件并导入Profile模型,如下所示:
@login_required
def edit(request):
if request.method == 'POST':
user_form = UserEditForm(instance=request.user,data=request.POST)
profile_form = ProfileEditForm(instance=request.user.profile,data=request.POST,files=request.FILES)
if user_form.is_valid() and profile_form.is_valid():
user_form.save()
profile_form.save()
else:
user_form = UserEditForm(instance=request.user)
profile_form = ProfileEditForm(instance=request.user.profile)
template = "account/edit.html"
context = {'user_form':user_form}
return render(request,template,context)
- 使用login_required装饰器是因为用户必须经过身份验证才能编辑他们的配置文件。
- UserEditForm用于存储内置用户模型的数据
- ProfileEditForm用于存储自定义概要模型中的附加概要数据。
- 为了验证提交的数据,将执行两个表单的is_valid()方法。如果两个表单都包含有效的数据,将保存两个表单,调用save()方法来更新数据库中相应的对象。
将以下URL模式添加到account应用程序的urls.py文件中:
{% extends "base.html" %}
{% block title %}Edit your account{% endblock %}
{% block content %}
Edit your account
You can edit your account using the following form:
{{ user_form.as_p }}
{{ profile_form.as_p }}
{% csrf_token %}
{% endblock %}
表单中包含enctype=”multipart/form-data”来启用文件上传。
使用HTML表单来提交user_form和profile_form表单。
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net