前面章節介紹了用戶的登錄,退出。這一章將介紹用戶的注冊。首先需要創建一個表單來讓用戶填寫用戶名,密碼等信息。創建UserRegistrationFrom表單。並指定model為User類
from django.contrib.auth.models import User
class UserRegistrationForm(forms.ModelForm):
password=forms.CharField(label=u"密碼")
password2=forms.CharField(label=u"重復輸入密碼")
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(u'密碼不匹配')
return cd['password2']
在這里定義了clean_password2用於校驗兩次輸入的密碼是否不相同,如果不同則拋出異常。這個函數在調用user_form.is_valid()的時候將會被觸發調用
接下來在views.py中添加處理函數:
def register(request):
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']) #使用set_password方法將用戶的密碼進行加密后再進行保存操作
new_user.save()
return render(request,'blog/register_done.html',{'new_user':new_user})
else:
user_form=UserRegistrationForm()
return render(request,'blog/register.html',{'user_form':user_form})
當用戶注冊成功,返回register_done頁面,初始訪問的時候返回register頁面
在blog應用中的url中添加路由配置:
url(r'^register/$',views.register,name='register'),
在templates/blog下新添加register.html和register_done.html
register.html代碼如下
{% extends "blog/base.html" %}
{% block title %}創建新用戶{% endblock %}
{% block content %}
<h1>創建新用戶</h1>
<p>請填寫如下表單:</p>
<form action="." method="post">
{{ user_form.as_p }}
{% csrf_token %}
<p><input type="submit" value="Create my account"></p>
</form>
{% endblock %}
register_done.html代碼如下:
{% extends "blog/base.html" %}
{% block title %}歡迎{% endblock %}
{% block content %}
<h1>歡迎 {{ new_user.first_name }}!</h1>
<p>已經成功創建用戶 <a href="{% url "login" %}">請登錄</a>.</p>
{% endblock %}
在url中輸入http://127.0.0.1:8000/account/register/進入注冊界面

注冊完成后提示注冊成功,並附上了登錄的鏈接

擴展用戶模型:
到目前為止,我們所有的用戶都是通過User類內置的元素來編輯的。但是User模型只有固定的一些字段。如果我們想擴展User的字段就需要創建一個profile模型來包含我們想增加的字段。並且和django中的User做一對一的關聯
首先在models.py中添加如下代碼:user一對一關聯用戶和profile。另外還定義了date_of_birth和photo字段,如果想要上傳圖片需要安裝Pillow來管理圖片。
class Profile(models.Model):
user=models.OneToOneField(settings.AUTH_USER_MODEL)
#通過OneToOneField將profile和User類關聯起來
date_of_birth=models.DateTimeField(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)
class Profile_admin(admin.ModelAdmin):
list_display = ['user','date_of_birth','photo']
在setting.py中添加圖片的存放路徑:這里設置存放在/media路徑。MEDIA_URL 是管理用戶上傳的多媒體文件的主URL,MEDIA_ROOT是這些文件在本地保存的路徑
MEDIA_URL='/media/'
MEDIA_ROOT=os.path.join(BASE_DIR,'media/')
在主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)
下面開始進行數據庫遷移:
zhf@zhf-maple:~/py_prj/mysite$ python manage.py makemigrations
Migrations for 'blog':
blog/migrations/0005_profile.py
- Create model Profile
zhf@zhf-maple:~/py_prj/mysite$ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, blog, contenttypes, sessions, taggit
Running migrations:
Applying blog.0005_profile... OK
在admin.py中進行注冊:
admin.site.register(Profile,Profile_admin)
如果我們需要用戶在線編輯他們的profile,需要定義模型,在forms.py中添加如下代碼:
class UserEditForm(forms.ModelForm):
class Meta:
model=User
fields=("first_name","last_name","email")
class ProfileEditForm(forms.ModelForm):
class Meta:
model=Profile
fields=('date_of_birth','photo')
這兩個表單(forms)的功能:
- UserEditForm:允許用戶編輯它們的first name,last name, e-mail 這些儲存在User模型(model)中的內置字段。
- ProfileEditForm:允許用戶編輯我們存儲在定制的Profile模型(model)中的額外數據。用戶可以編輯他們的生日數據以及為他們的profile上傳一張照片。
在views,py的register函數中的new_user.save()后添加
profile=Profile.objects.create(user=new_user)。這給每個用戶添加了一個profile對象。注意,在這段代碼添加前的用戶是沒有這個profile對象的,只有這個profile對象添加之后的用戶才有這個對象。
下面添加edit函數來編輯profile
@login_required(login_url='/account/login')
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)
return render(request,'blog/edit.html',{'user_form':user_form,'profile_form':profile_form})
我們使用login_required裝飾器decorator是因為用戶編輯他們的profile必須是認證通過的狀態。在這個例子中,我們使用兩個模型(model)表單(forms):UserEditForm用來存儲數據到內置的User模型(model)中,ProfileEditForm用來存儲額外的profile數據。為了驗證提交的數據,通過is_valid()方法是否都返回True我們來檢查每個表單(forms)。在這個例子中,我們保存兩個表單(form)來更新數據庫中對應的對象。
最后在blog應用中的urls.py中添加路由:
url(r'^edit/$', views.edit, name='edit'),
登錄帳號后輸入http://127.0.0.1:8000/account/edit/進入編輯

進入admin界面也可以看到添加的profile對象

