在這個部分,咱們將要開始學習如何設計用戶系統,Django提供了一個叫「django.contrib.auth」的應用,咱們能夠用它來作出用戶註冊、登陸、註銷等一系列功能。html
17.用戶模型 python
在Django自帶的用戶系統中,用戶模型裏已經包含了以下數據:web
咱們想在用戶模型中增長一些額外的字段,如:數據庫
咱們只要更新模型就能夠實現上述的需求,編輯rango/models.py文件,先在頭部加入一行:django
rango/models.py:瀏覽器
from django.contrib.auth.models import User
rango/models.py:ide
class UserProfile(models.Model): # 這一句是必須的,連接UserProfile到Django的用戶模型 user = models.OneToOneField(User) # 咱們想要增長的額外字段 website = models.URLField(blank=True) picture = models.ImageField(upload_to='profile_images', blank=True) # 重寫__str__方法,讓它在被調用時顯示用戶名 def __str__(self): return self.user.username
在這兩個字段中,咱們設置了「blank=True」,正如字面意思顯示,這是容許該字段爲空的節奏。post
注意在「ImageField」字段中有一個「upload_to」屬性,它指定了儲存用戶頭像的文件夾,這個叫「profile_images」的文件夾將放在settings.py中指定的MEDIA_ROOT文件夾下,換句話說,它的路徑將是:學習
rangoproject/media/profile_images/
模型作好後,咱們須要更新一下數據庫,而後在dos命令提示符下運行以下命令:網站
$ python manage.py makemigrations rango
繼續在dos命令提示符下運行命令:
$ python manage.py migrate
18.安裝PIL
Django的ImageField使用Python的圖像庫PIL,若是你沒有安裝PIL,那麼須要先安裝它。
在Windows平臺的Python 3.2環境下,捨得推薦安裝這個版本:
https://pypi.python.org/pypi/Pillow/2.6.0
找到其中的Pillow-2.6.0.win32-py3.2.exe (md5) ,下載下來以後,直接安裝就能夠了。注意,這是適用於Python 32位的版本。
19.在管理界面註冊UserProfile
編輯rango/admin.py 文件,讓它變成下面這個樣子:
rango/admin.py:
from django.contrib import admin from rango.models import Category, Page from rango.models import UserProfile class PageAdmin(admin.ModelAdmin): list_display = ('title', 'category', 'url') class CategoryAdmin(admin.ModelAdmin): prepopulated_fields = {'slug':('name',)} admin.site.register(Category, CategoryAdmin) admin.site.register(Page, PageAdmin) admin.site.register(UserProfile)
20.建立用戶註冊視圖和模板
「用戶註冊」功能將容許用戶在咱們的網站上建立帳號,咱們須要爲這個功能添加視圖和相應的模板。下面是要完成的工做:
讓咱們一步步來實現這些內容吧!編輯rango/forms.py 文件,讓它變成下面這個樣子:
rango/forms.py:
class UserForm(forms.ModelForm): password = forms.CharField(widget=forms.PasswordInput()) class Meta: model = User fields = ('username', 'email', 'password') class UserProfileForm(forms.ModelForm): class Meta: model = UserProfile fields = ('website', 'picture')
你會發現咱們在UserForm和UserProfileForm這倆表單中加入了兩個Meta類,每一個Meta類都帶有一個model字段,它會告訴程序這個表單將要關聯到數據庫中的哪一個表,好比UserForm關聯到的是User表。
最後,別忘了將forms.py頭部改爲下面這樣:
rango/forms.py:
from django import forms from django.contrib.auth.models import User from rango.models import Category, Page, UserProfile
搞完上面這些,讓咱們來建立用戶註冊視圖。
編輯rango/views.py,添加如下內容:
rango/views.py(注意將第一行代碼放到文件頭部):
from rango.forms import UserForm, UserProfileForm def register(request): # registered:註冊成功與否的信號. # 先默認爲False,等註冊成功後程序會將其改成True registered = False # 若是是一個HTTP POST請求, 就意味着將要處理表單數據. if request.method == 'POST': # 嘗試從提交的信息中獲取數據。 # 注意UserForm和UserProfileForm都會用到這些數據. user_form = UserForm(data=request.POST) profile_form = UserProfileForm(data=request.POST) # 若是表單有效... if user_form.is_valid() and profile_form.is_valid(): # 將用戶表單數據儲存到數據庫. user = user_form.save() # 用set_password方法處理密碼. # 而後儲存用戶數據. user.set_password(user.password) user.save() # 如今來處理UserProfile表單. # 先設置commit爲False. # 這個信號用來延遲數據儲存動做,直至咱們將數據準備好。 profile.user = user # 用戶是否提供圖片(頭像)? # 若是有,則要將其儲存進數據庫. if 'picture' in request.FILES: profile.picture = request.FILES['picture'] #儲存UserProfile數據. profile.save() # 更新registered信號,將其改成True,此信號將通知模板系統用戶已完成註冊. registered = True # 表單無效或出錯 # 將故障代碼顯示給終端及用戶. else: print(user_form.errors, profile_form.errors) # 非HTTP POST請求, 那咱們就僅僅渲染一下兩個空白表單,以供用戶輸入. else: user_form = UserForm() profile_form = UserProfileForm() # 根據內容渲染模板. return render(request, 'rango/register.html', {'user_form': user_form, 'profile_form': profile_form, 'registered': registered} )
接下來建立註冊模板,建立templates/rango/register.html,加入以下內容:
templates/rango/register.html:
<!DOCTYPE html> <html> <head> <title>Rango</title> </head> <body> <h1>註冊Rango</h1> {% if registered %} Rango說: <strong>很是感謝您的註冊!</strong> <a href="/rango/">返回到首頁.</a><br /> {% else %} Rango說: <strong>註冊請點這裏!</strong><br /> <form id="user_form" method="post" action="/rango/register/" enctype="multipart/form-data"> {% csrf_token %} <!-- 顯示每一個表單,as_p方法會將每一個元素處理爲段落。這樣可確保每一個元素顯示爲一個新行,看起來很整潔]--> ` user_form`.`as_p ` ` profile_form`.`as_p ` <!-- 提供一個可點擊的按鈕,用來提交表單. --> <input type="submit" name="submit" value="註冊" /> </form> {% endif %} </body> </html>
視圖和模板都好了,下面咱們該處理URL映射,將它們都連到一塊兒。編輯rango/urls.py,改爲下面這樣:
rango/urls.py:
urlpatterns = patterns('', url(r'^$', views.index, name='index'), url(r'^about/$', views.about, name='about'), url(r'^category/(?P<category_name_slug>\w+)$', views.category, name='category'), url(r'^add_category/$', views.add_category, name='add_category'), url(r'^category/(?P<category_name_slug>\w+)/add_page/$', views.add_page, name='add_page'), url(r'^register/$', views.register, name='register'), # 新增內容在這裏! )
最後,咱們要修改首頁模板(templates/rango/index.html),把「註冊」連接放到首頁中。請在</body>標籤前添加如下內容:
templates/rango/index.html:
<a href="/rango/register/">註冊</a><br />
咱們來看檢查一下工做成果,在瀏覽器中輸入:http://127.0.0.1:8000/rango/register,你會看到下面這樣的頁面:
【未完待續】