天天看點

django python3會員中心_python程式設計:從入門到實踐學習筆記-Django開發使用者賬戶(三)...

讓使用者擁有自己的資料

這部分我們将建立一個系統,确定各項資料所屬的使用者,再限制對頁面的通路,讓使用者隻能使用自己的資料。

修改模型Topic,讓每個主題都歸屬特定使用者。

使用@login_required限制通路

裝飾器是放在函數定義前面的指令,python在函數運作前,根據它來修改函數代碼的行為。

裝飾器@login_required:讓特定的頁面隻允許已登入的使用者通路。

1.限制對topics頁面的通路

修改learning_logs/views.py

#--snip--

from django.core.urlresolvers import reverse

from django.contrib.auth.decorators import login_required

from .models import Topic, Entry

#--snip--

@login_required

def topics(request):

#--snip--

加上裝飾器之後,python會在運作topics()的代碼前先運作login_required()的代碼。

login_required()會檢查使用者是否已登入,僅當使用者已登入時,django才運作topics()。如果使用者未登入,則重定向到登入頁面。

為實作重定向,修改settings.py,在檔案末尾加上 LOGIN_URL = '/users/login/' 。現在未登入的使用者會重定向到 LOGIN_URL 指定的URL。

2.全面限制對項目“學習筆記”的通路

現在,我們不限制對首頁、注冊、登出頁面的通路,而限制對其他所有頁面的通路。

在learning_logs/views.py中,除了index()意外,每個視圖都加上 @login_required。

--snip--

@login_required

def topics(request):

--snip--

@login_required

def topic(request, topic_id):

--snip--

@login_required

def new_topic(request):

--snip--

@login_required

def new_entry(request, topic_id):

--snip--

@login_required

def edit_entry(request, entry_id):

--snip--

将資料關聯到使用者

修改模型Topic,添加一個關聯到使用者的外鍵。然後必須對資料庫進行遷移。最後對部分視圖進行修改,使其隻顯示與目前使用者登入的相關聯的資料。

1.修改模型Topic

修改learning_logs/models.py

from django.db import models

from django.contrib.auth.models import User

class Topic(models.Model):

text = models.CharField(max_length=200)

date_added = models.DateTimeField(auto_now_add=True)

owner = models.ForeignKey(User)

def __str__(self):

return self.text

class Entry(models.Model):

--snip--

2.确定目前有哪些使用者

為了簡單,我們将既有主題都關聯到超級使用者上,先确定超級使用者的id,打開shell。

django python3會員中心_python程式設計:從入門到實踐學習筆記-Django開發使用者賬戶(三)...

确定目前使用者隻有admin,id為1。(或者還有其他你自己建立的使用者)

3.遷移資料庫

擷取id之後,遷移資料庫。

django python3會員中心_python程式設計:從入門到實踐學習筆記-Django開發使用者賬戶(三)...

首先執行指令makemigrations後,django指出我們視圖給既有模型Topic添加一個必不可少(不可為空)的字段(無預設值),并提供了兩種選擇:要麼現在提供預設值,要麼退出并在models.py中添加預設值。在這裡我選了第一個選項,輸入預設值,接着輸入了使用者id = 1。最後django使用這個值遷移資料庫,在模型Topic中添加字段owner。

接下來執行遷移,執行指令python manage.py migrate。

django python3會員中心_python程式設計:從入門到實踐學習筆記-Django開發使用者賬戶(三)...

隻允許使用者通路自己的主題

目前不管哪個使用者登入,都能看到所有主題,現在我們讓使用者隻能看到自己的主題。

修改learning_logs/views.py

#--snip--

@login_required

def topics(request):

topics = Topic.objects.filter(owner=request.user).order_by('date_added')

context = {'topics': topics}

return render(request, 'learning_logs/topics.html', context)

#--snip--

使用者登入後,request對象會有一個user屬性,其存儲了有關該使用者的所有資訊。 filter() 用于過濾序列,過濾掉不符合條件的元素,傳回由符合條件元素組成的新清單。在這裡我們用這個函數從資料庫中隻擷取 owner 屬性為目前使用者的Topic對象。

保護使用者的主題

在此之前,已登入的使用者可輸入URLhttp://127.0.0.1:8000/topics/1/來通路顯示相應主題的頁面。

為修複這種問題,,我們在視圖函數topic()擷取請求的條目前執行檢查。

from django.shortcuts import render

from django.http import HttpResponseRedirect, Http404

from django.core.urlresolvers import reverse

#--snip--

@login_required

def topic(request, topic_id):

topic = Topic.objects.get(id=topic_id)

if topic.owner != request.user:

raise Http404

entries = topic.entry_set.order_by('-date_added')

context = {'topic': topic, 'entries': entries}

return render(request, 'learning_logs/topic.html', context)

#--snip--

渲染網頁前檢查該主題是否屬于目前登入的使用者,如果不是,則404。

保護頁面edit_entry

接下來保護頁面http://127.0.0.1:8000/edit_entry/1/。修改views.py

#--snip--

@login_required

def edit_entry(request, entry_id):

entry = Entry.objects.get(id=entry_id)

topic = entry.topic

if topic.owner != request.user:

raise Http404

if request.method != 'POST':

#--snip--

将新主題關聯到目前使用者

目前,添加新主題的頁面沒有将新主題關聯到特定使用者。修改views.py

#--snip--

@login_required

def new_topic(request):

if request.method != 'POST':

form = TopicForm()

else:

form = TopicForm(request.POST)

if form.is_valid():

new_topic = form.save(commit=False)

new_topic.owner = request.user

new_topic.save()

return HttpResponseRedirect(reverse('learning_logs:topics'))

context = {'form': form}

return render(request, 'learning_logs/new_topic.html', context)

#--snip--

首先調用form.save(commit=False)是為了先修改新主題,暫時不送出到資料庫中。接下來将新主題的 owner屬性設定為目前使用者後,最後在儲存送出到資料庫中。

現在這個項目允許任何人注冊,而且每個使用者可以添加任意數量的新主題。每個使用者都隻能通路自己的資料,無論是檢視資料、輸入新資料還是修改就資料都是如此。