學(xué)習(xí)Django(2)

先把github鏈接放上來:
https://github.com/q100036q/python_demo_learning_logs
上一篇文章從創(chuàng)建一個(gè)django環(huán)境開始椭员,一直到制作了一個(gè)網(wǎng)站煮纵,可以保存主題和內(nèi)容岭辣。這篇文章主要描述使用賬號(hào)來管理這個(gè)網(wǎng)站。

第一:增加新的主題和內(nèi)容:

1.首先引入forms模塊中的ModelForm來創(chuàng)建一個(gè)新的表單格式谴古,代碼如下:

 #forms.py
 from django import forms;

 from .models import Topic,Entry;

class TopicForm(forms.ModelForm):
    class Meta:
        model = Topic;
        fields = ['text'];
        labels = {'text':''};

class EntryForm(forms.ModelForm):
    class Meta:
        model = Entry;
        fields = ['text'];
        labels = {'text':''};
        widgets = {'text':forms.Textarea(attrs = {'cols':80})};#這段代碼作用是

這里針對(duì)主題和內(nèi)容分別定制了兩個(gè)表單,它內(nèi)嵌Meta 類,告訴Django根據(jù)哪個(gè)模型創(chuàng)建表單经磅,以及在表單中包含哪些字段。

2.接下來钮追,修改urls文件去添加主題:

#urls.py
from django.conf.urls import url;

from . import views;
app_name='learning_logs'

urlpatterns = [
    url(r'^$',views.index,name = 'index'),
    url(r'^topics/$',views.topics,name = 'topics'),
    url(r'^topics/(?P<topic_id>\d+)/$',views.topic,name = 'topic'),
    url(r'^new_topic/&',views.new_topic,name = 'new_topic'),
    url(r'^new_entry/(?P<topic_id>\d+)/$',views.new_entry,name = 'new_entry'),
    #url(r'^edit_entry/(?P<entry_id>\d+)/$',views.edit_entry,name = 'edit_entry'),這段代碼之后再編輯內(nèi)容的時(shí)候去解開注釋
]

這里就是分別對(duì)http://localhost:8000/new_topic/http://localhost:8000/new_entry/1/分別進(jìn)行匹配预厌,然后去視圖層注冊這兩個(gè)函數(shù)。

3.修改視圖層

#views.py
from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from .models import Topic,Entry;
from .forms import TopicForm,EntryForm;
--snip--#由于代碼太多元媚,這里使用這個(gè)表示之前的其他代碼
def new_topic(request):
"""添加新主題""" 
    if request.method != 'POST':
    # 未提交數(shù)據(jù):創(chuàng)建一個(gè)新表單
       form = TopicForm()
    else:
    # POST提交的數(shù)據(jù),對(duì)數(shù)據(jù)進(jìn)行處理
         form = TopicForm(request.POST) 
         if form.is_valid(): 
             form.save() 
             return HttpResponseRedirect(reverse('learning_logs:topics'))
    context = {'form': form}
    return render(request, 'learning_logs/new_topic.html', context)
def new_entry(request,topic_id):
    topic = Topic.objects.get(id = topic_id);
    if request.method != 'POST':
        form = EntryForm();
    else:
        form = EntryForm(data = request.POST);
        if form.is_valid():
            new_entry = form.save(commit = False);
            new_entry.topic = topic;
            new_entry.save();
            return HttpResponseRedirect(reverse('learning_logs:topic',args = [topic_id]));
    context = {'topic':topic,'form':form};
    return render(request,'learning_logs/new_entry.html',context);

這兩個(gè)函數(shù)的最終的作用就是當(dāng)新的表單內(nèi)容提交后轧叽,通過HttpResponseRedirect模塊分別重新定向到topics.html和topic.html頁面。首先對(duì)請求類型進(jìn)行判斷刊棕,是GET請求炭晒,就創(chuàng)建一個(gè)可被用戶編輯的空表單,經(jīng)過字典的方式傳遞給模板甥角。若是POST請求网严,則對(duì)表單數(shù)據(jù)進(jìn)行處理,使用用戶輸入的數(shù)據(jù)并保存嗤无,在定向到之前顯示數(shù)據(jù)的界面震束。
關(guān)于new_entry函數(shù)內(nèi)容,稍有些不同的地方:調(diào)用save() 時(shí)当犯,我們傳遞了實(shí)參commit=False 垢村,讓Django創(chuàng)建一個(gè)新的條目對(duì)象,并將其存儲(chǔ)到new_entry 中嚎卫,但不將它保存到數(shù)據(jù)庫中嘉栓。我們將new_entry 的屬性topic 設(shè)置為在這個(gè)函數(shù)開頭從數(shù)據(jù)庫中獲取的主題,然后調(diào)用save() ,且不指定任何實(shí)參侵佃。這將把條目保存到數(shù)據(jù)庫麻昼,并將其與正確的主題相關(guān)聯(lián)。
我們將用戶重定向到顯示相關(guān)主題的頁面趣钱。調(diào)用reverse() 時(shí)涌献,需要提供兩個(gè)實(shí)參:要根據(jù)它來生成URL的URL模式的名稱;列表args 首有,其中包含要包含在URL中的所有實(shí)參燕垃。在這里,列表args 只有一個(gè)元素——topic_id 井联。接下來卜壕,調(diào)用HttpResponseRedirect() 將用戶重定向到顯示新增條目所屬主題的頁面,用戶將在該頁面的條目列表中看到新添加的條目烙常。

4.創(chuàng)建模板頁面

根據(jù)以往經(jīng)驗(yàn)轴捎,視圖層結(jié)束之后就是模板了,下面把兩個(gè)新增加內(nèi)容代碼寫出來:

<!--new_topic.html-->
{% extends 'learning_logs/base.html' %}
{% block content %}
<p>Add a new topic:</p>
<form action="{% url 'learning_logs:new_topic' %}" method = 'post'>
    {% csrf_token %}
    {{ form.as_p }}
    <button name = 'submit'>add topic</button>
</form>
{% endblock content %}

<!--new_entry.html-->
{% extends "learning_logs/base.html" %}
{% block content %}
<p><a href = "{% url 'learning_logs:topic' topic.id %}">{{ topic }}</a></p>
<p>Add a new entry:</p>
<form action="{% url 'learning_logs:new_entry' topic.id %}"method = 'post'>
    {% csrf_token %}
    {{ form.as_p }}
    <button name = 'submit'>add entry</button>
</form>
{% endblock content %}

首先定義了一個(gè)HTML的表單蚕脏,參數(shù)action告訴我們將表單傳遞到哪侦副,參數(shù)method告知這次傳遞使用的是POST的方式,{% csrf_token %}標(biāo)簽防止攻擊者利用表單來對(duì)服務(wù)器進(jìn)行未授權(quán)的訪問驼鞭,模板變量{{ form.as_p }} 可讓Django自動(dòng)創(chuàng)建顯示表單所需的全部字段秦驯。修飾符as_p 讓Django以段落格式渲
染所有表單元素。最后在創(chuàng)建一個(gè)提交按鈕來執(zhí)行這些內(nèi)容挣棕。
new_entry.html的內(nèi)容和之前類似译隘,多了一個(gè)超鏈接回到上一層頁卡,action中多傳遞了一個(gè)參數(shù)洛心,給表單進(jìn)行使用固耘,能在第一步的第3條中通過它獲得指定的數(shù)據(jù)。

5.編輯內(nèi)容文本

為了給每個(gè)條目的內(nèi)容進(jìn)行修改词身,新增加一個(gè)模塊來完成它厅目,老規(guī)矩,先去urls.py中進(jìn)行注冊:

#urls.py
--snip--#這里偷下懶法严,不再將全部代碼拷貝璧瞬,后文都用這個(gè)代替已有代碼
urlpatterns = [
    --snip--
    # 用于編輯條目的頁面
   url(r'^edit_entry/(?P<entry_id>\d+)/$',views.edit_entry,name = 'edit_entry'),
]

上面代碼匹配http://localhost:8000/edit_entry/1/這樣的一個(gè)路徑,接著渐夸,去views.py中增加視圖函數(shù):

#views.py
--snip--
def edit_entry(request,entry_id):
    entry = Entry.objects.get(id = entry_id);
    topic = entry.topic;
    if request.method != 'POST':
        form = EntryForm(instance=entry);
    else:
        form = EntryForm(instance=entry,data = request.POST);
        if form.is_valid():
            form.save();
            return HttpResponseRedirect(reverse('learning_logs:topic',args = [topic.id]));
    context = {'entry':entry,'topic':topic,'form':form};
    return render(request,'learning_logs/edit_entry.html',context);

這個(gè)函數(shù)和上面new_entry()函數(shù)很像,先通過id獲得數(shù)據(jù)庫內(nèi)容渔欢,然后判斷請求來創(chuàng)建表單墓塌,不同的是,這次,創(chuàng)建表單的函數(shù)傳遞了instance參數(shù)苫幢,目的是根據(jù)這個(gè)參數(shù)內(nèi)容來填充表單访诱。因?yàn)檫@個(gè)內(nèi)容肯定是指定了條目topic的,所以不需要和之前那樣保存本地指定條目再保存韩肝,可以直接保存到數(shù)據(jù)庫触菜。接下來,去編寫新的html文件使用它哀峻。

<!--edit_entry.html-->
{% extends 'learning_logs/base.html'%}
{% block content %}
<p><a href="{% url 'learning_logs:topic' topic.id %}">{{topic}}</a></p>
<p>Edit entry:</p>
<form action="{% url 'learning_logs:edit_entry' entry.id %}" method = 'post'>
    {% csrf_token %}
    {{form.as_p}}
    <button name = 'submit'>save changes</button>
</form>
{% endblock content %}

內(nèi)容和之前差不多涡相,多了一個(gè)鏈接去返回到條目的頁面。
最后給用戶提供一個(gè)編輯已有內(nèi)容的入口剩蟀,修改下topic.html:

#topic.html
{% extends "learning_logs/base.html" %}
{% block content %}
<p>Topics: {{ topic }}</p>
<p>Entries:</p>
<p>
    <a href="{% url 'learning_logs:new_entry' topic.id %}">add new entry</a>
</p>
<ul>
    {% for entry in entries %}
    <li>
        <p>{{ entry.date_add|date:'M d,Y H:i'}}</p>
        <p>{{ entry.text|linebreaks }}</p>
        <p>
            <a href="{% url 'learning_logs:edit_entry' entry.id %}">edit entry</a>
        </p>
    </li>
    {% empty %}
    <li>There are no entries for this topic yet.</li>
    {% endfor %}
</ul>
{% endblock content %}

至此催蝗,給我們的項(xiàng)目進(jìn)行新增條目和新增內(nèi)容,并編輯內(nèi)容都完成了育特,接下來將為項(xiàng)目增加賬戶控制丙号。

第二:創(chuàng)建用戶賬戶

為了單獨(dú)管理賬戶系統(tǒng),我們新建一個(gè)應(yīng)用程序來處理相關(guān)功能缰冤∪В回想一下之前創(chuàng)建learning_logs的方法,使用命令startapp 來創(chuàng)建一個(gè)名為users 的應(yīng)用程序棉浸,其結(jié)構(gòu)與應(yīng)用程序learning_logs 相同:

python manage.py startapp users

接著修改主項(xiàng)目learning_log文件夾下的settings.py和urls.py怀薛,將users加入到項(xiàng)目中來。

#setting.py
--snip--
INSTALLED_APPS = (
--snip--
# 我的應(yīng)用程序
    'learning_logs',
    'users',
)
--snip--
#urls.py
--snip--
url(r'^users/',include('users.urls',namespace='users')),
--snip--

下面我們將依次對(duì)登錄涮拗,注銷乾戏,注冊三個(gè)功能進(jìn)行處理。

1.登錄

注意三热,之后基本都是修改users文件夾下的內(nèi)容鼓择,若修改別的文件夾,會(huì)特殊說明就漾。
修改urls.py添加登錄頁面的url模式:

#urls.py
from django.conf.urls import url
from django.contrib.auth.views import LoginView
from . import views
app_name='users'#一定要加這個(gè)
urlpatterns = [
    url(r'^login/$',LoginView.as_view(template_name='users/login.html'),name='login'),
    #url(r'^logout/$',views.logout_view,name='logout'),暫時(shí)注釋注銷路徑
    #url(r'^register/$',views.register,name='register'),暫時(shí)注釋注冊路徑
]

登錄頁面的URL模式與URL http://localhost:8000/users/login/匹配呐能。這里我們使用django提供的默認(rèn)登錄視圖,就不用為了登錄再去創(chuàng)建修改views文件了抑堡,為此引入了模塊LoginView摆出,django的類視圖擁有自動(dòng)查找指定方法的功能, 通過調(diào)用是通過as_view()方法實(shí)現(xiàn),所以首妖,這里這么寫的意思就是給默認(rèn)的視圖提供模板偎漫。
關(guān)于as_view()的工作流程可以看這個(gè)文章:http://www.reibang.com/p/17860becea09
之后,去完成這個(gè)模板文件新建文件夾template,在其中建立文件夾users。新建文件login.html:

<!--login.html-->
{% extends "learning_logs/base.html" %}
{% block content %}
{% if form.errors %}
<p>Your username and password didn't match.Please try again.</p>
{% endif %}
<form method="post" action="{% url 'users:login' %}">
    {% csrf_token %}
    {{ form.as_p }}
    <button name="submit">Log in</button>
    <input type="hidden" name="next" value="{% url 'learning_logs:index' %}"/>
</form>
{% endblock content %}

如果表單的errors 屬性被設(shè)置刑峡,我們就顯示一條錯(cuò)誤消息夫晌,指出輸入的用戶名—密碼對(duì)與數(shù)據(jù)庫中存儲(chǔ)的任何用戶名—密碼對(duì)都不匹配怕犁。最后面的input type="hidden"證明這是一個(gè)隱藏表單拍柒,傳遞的參數(shù)value告知django灯节,登陸之后重定向到主頁汁掠。
下面史隆,修改一下base.html文件魂务,增加一個(gè)登錄的鏈接入口。

<!--learning_logs/base.html-->
<p>
<a href="{% url 'learning_logs:index' %}">Learning Log</a>-
<a href="{% url 'learning_logs:topics' %}">Topics</a>-
{% if user.is_authenticated %}
    Hello,{{ user.username }}.
    <!--<a href="{% url 'users:logout' %}">Log out</a>暫時(shí)注釋掉注銷的入口-->
{% else %}
    <!--<a href="{% url 'users:register' %}">register</a>-暫時(shí)注釋掉注冊的入口-->
    <a href="{% url 'users:login' %}">Log in</a>
{% endif %}
</p>
{% block content %}{% endblock content %}

在Django身份驗(yàn)證系統(tǒng)中泌射,每個(gè)模板都可使用變量user 粘姜,這個(gè)變量有一個(gè)is_authenticated 屬性:如果用戶已登錄,該屬性將為True 魄幕,否則為False 相艇。
現(xiàn)在可以訪問http://localhost:8000/users/login/,若登錄了顯示的是你的用戶名纯陨,否則坛芽,點(diǎn)擊登錄按鈕跳轉(zhuǎn)到登錄界面試試吧。若已經(jīng)登錄了翼抠,可以先注銷咙轩,一般保存在瀏覽器的設(shè)置里面,清空之后再進(jìn)去就等點(diǎn)擊登錄了阴颖。

2.注銷

修改urls.py活喊,指定索引url路徑,解開上面第1段中的注釋量愧。下面去編寫視圖函數(shù)logout_view()钾菊。

#views.py
from django.shortcuts import render
from django.http import HttpResponseRedirect as HRR
from django.urls import reverse
from django.contrib.auth import logout
# Create your views here.
def logout_view(request):
    logout(request)
    return HRR(reverse('learning_logs:index'))

我們從django.contrib.auth中導(dǎo)入了函數(shù)logout() ,它要求將request 對(duì)象作為實(shí)參偎肃,會(huì)將存儲(chǔ)在用戶session的數(shù)據(jù)全部清空煞烫。然后,我們重定向到主頁累颂。接著修改base.html滞详,增加注銷的入口鏈接。這個(gè)在第1段登錄的里面已經(jīng)寫過被注釋了紊馏,解開就可以料饥。

3.注冊

雖然注冊比上面麻煩一些,但是基礎(chǔ)流程是沒有變化的朱监,首先去改urls.py岸啡,這里也把上面的注釋解開就行,匹配的是http://localhost:8000/users/register/
修改views.py赫编,這里面要導(dǎo)入一些別的模塊:

 #views.py
--snip--
from django.contrib.auth import logout,login,authenticate
from django.contrib.auth.forms import UserCreationForm
--snip--
def register(request):
    if request.method != 'POST':
        form = UserCreationForm()
    else:
        form = UserCreationForm(data=request.POST)
        if form.is_valid():
            new_user = form.save()
            authenticated_user = authenticate(username=new_user.username,password=request.POST['password1'])
            login(request,authenticated_user)
            return HRR(reverse('learning_logs:index'))
    context = {'form':form}
    return render(request,'users/register.html',context)

使用 authenticate() 函數(shù)認(rèn)證給出的用戶名和密碼凰狞, 而要登錄一個(gè)用戶篇裁,使用 login() 。該函數(shù)接受一個(gè) HttpRequest 對(duì)象和一個(gè) User 對(duì)象作為參數(shù)并使用Django的會(huì)話( session )框架把用戶的ID保存在該會(huì)話中赡若。UserCreationForm是提供的默認(rèn)表,包括username和兩個(gè)password团甲。
關(guān)于login函數(shù)和authenticate函數(shù)看這里:https://www.cnblogs.com/ccorz/p/6357815.html
下面逾冬,給這個(gè)注冊視圖增加模板:

<!--register.html-->
{% extends "learning_logs/base.html" %}
{% block content %}
    <form method="post" action="{% url 'users:register' %}">
        {% csrf_token %}
        {{ form.as_p }}
        <button name="submit">register</button>
        <input type="hidden" name="next" value="{% url 'learning_logs:index' %}"/>
    </form>
{% endblock content %}

和login.html幾乎一樣,最后去修改base.html躺苦,解開注釋的代碼身腻,增加注冊賬號(hào)的入口。

第三:屬于用戶自己的數(shù)據(jù)

1.裝飾器@login_required限制訪問

我們將修改模型Topic 匹厘,讓每個(gè)主題都?xì)w屬于特定用戶嘀趟。Django提供了裝飾器@login_required ,對(duì)于某些頁面愈诚,只允許已登錄的用戶訪問它們她按。這里開始,代碼回到learning_logs應(yīng)用程序內(nèi)炕柔,先去給views.py里面除了index()主頁函數(shù)之外的每一個(gè)函數(shù)的頭部都增加裝飾器:

#views.py
--snip--
from django.contrib.auth.decorators import login_required
--snip--
@login_required
def topics(request):
"""顯示所有的主題"""
--snip--

login_required() 的代碼檢查用戶是否已登錄酌泰,僅當(dāng)用戶已登錄時(shí),Django才運(yùn)行topics() 的代碼匕累。如果用戶未登錄陵刹,就重定向到登錄頁面。
為實(shí)現(xiàn)這種重定向欢嘿,我們需要修改settings.py衰琐,讓Django知道到哪里去查找登錄頁面。請?jiān)趕ettings.py末尾添加如下代碼:

#learning_log/setting.py
""" 項(xiàng)目learning_log的Django設(shè)置
--snip--
# 我的設(shè)置
LOGIN_URL = '/users/login/'

現(xiàn)在炼蹦,如果未登錄的用戶請求裝飾器@login_required 的保護(hù)頁面羡宙,Django將重定向到settings.py中的LOGIN_URL 指定的URL。現(xiàn)在在未登錄的情況下嘗試訪問這些頁面框弛,將被重定向到登錄頁面辛辨。

2.關(guān)聯(lián)用戶主題

下面來修改模型Topic ,在其中添加一個(gè)關(guān)聯(lián)到用戶的外鍵瑟枫。因?yàn)樯婕暗叫薷膍odels斗搞,我們必須對(duì)數(shù)據(jù)庫進(jìn)行遷移。最后慷妙,我們必須對(duì)有些視圖進(jìn)行修改僻焚,使其只顯示與當(dāng)前登錄的用戶相關(guān)聯(lián)的數(shù)據(jù)。

#models.py
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Topic(models.Model):
    text = models.CharField(max_length = 200);
    date_added = models.DateTimeField(auto_now_add = True);
    owner = models.ForeignKey(User, on_delete=models.CASCADE);

    def __str__(self):
        return self.text;
--snip--

這里引入U(xiǎn)ser模型膝擂,并且作為一個(gè)外鍵生成owner字段虑啤。
注意:python3.7下使用models.ForeignKey時(shí)一定要傳入實(shí)參on_delete=models.CASCADE隙弛,作用是刪除主表,數(shù)據(jù)跟著一起刪除狞山。接下來進(jìn)行數(shù)據(jù)庫遷移:

python manage.py makemigrations learning_logs

此時(shí)因?yàn)槲覀兇a中沒有給owner一個(gè)默認(rèn)值全闷,會(huì)有報(bào)錯(cuò)提示,提供默認(rèn)值或者退出回到models.py中填寫默認(rèn)值萍启,這里輸入1总珠,立刻給一個(gè)默認(rèn)數(shù)據(jù),再輸入一次1勘纯,將之前創(chuàng)建的超級(jí)用戶作為owner局服,這里可以不使用超級(jí)用戶,在shell會(huì)話中可以查看之前注冊過的用戶名和id驳遵,新建一個(gè)工作窗口淫奔,輸入以下shell語句,查看用戶id:

python manage.py shell
from django.contrib.auth.models import User
User.objects.all()

若是覺得之前創(chuàng)建的用戶過多堤结,使用如下語句重置數(shù)據(jù)庫唆迁,并在這之后重新去創(chuàng)建超級(jí)用戶:

python manage.py flush

3.訪問自己的主題

當(dāng)前,不管你以哪個(gè)用戶的身份登錄霍殴,都能夠看到所有的主題媒惕。我們來改變這種情況,只向用戶顯示屬于自己的主題±赐ィ現(xiàn)在修改views.py的topics()函數(shù):

#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 對(duì)象將有一個(gè)user 屬性,這個(gè)屬性存儲(chǔ)了有關(guān)該用戶的信息月弛。代碼Topic.objects.filter(owner=request.user) 讓Django只從數(shù)據(jù)庫中獲取owner 屬性為當(dāng)前用戶的Topic 對(duì)象‰日担現(xiàn)在主題列表頁面已經(jīng)被限制了,只能顯示當(dāng)前登錄用戶所有的主題帽衙,但是如果更換用戶菜皂,使用url的方式訪問這個(gè)主題的內(nèi)容頁面,比如http://localhost:8000/topics/1/還是可以進(jìn)入厉萝,所以下面對(duì)每個(gè)主題的內(nèi)容頁面進(jìn)行限制:

#views.py
from django.shortcuts import render;
from django.http import HttpResponseRedirect,Http404;
from django.urls import reverse;
# Create your views here.
from django.contrib.auth.decorators import login_required;

from .models import Topic,Entry;
from .forms import TopicForm,EntryForm;


def check_topic_owner(request,topic):
    if topic.owner != request.user:
        raise Http404;
@login_required
def topic(request,topic_id):
    topic = Topic.objects.get(id = topic_id);
    check_topic_owner(request,topic);
    entries = topic.entry_set.order_by('-date_added');
    context = {'topic':topic,'entries':entries}
    return render(request,'learning_logs/topic.html',context);

引入Http404的目的是為了訪問失敗的時(shí)候給一個(gè)異常報(bào)錯(cuò)恍飘,這里當(dāng)該主題的用戶不是登錄用戶,就報(bào)這個(gè)異常谴垫。edit_entry這個(gè)函數(shù)也和topic函數(shù)一樣需要限制章母,這里就不重復(fù)了。

4.將新增加的主題關(guān)聯(lián)用戶

創(chuàng)建新主題時(shí)翩剪,你必須指定其owner 字段的值乳怎,否則會(huì)報(bào)錯(cuò)。這里要修改new_topic函數(shù):

#views.py
--snip--
@login_required
def new_topic(request):
    if request.method != 'POST':
        form = TopicForm();
    else:
        form = TopicForm(data = 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--

這里對(duì)比之前寫的new_topic函數(shù)修改了保存數(shù)據(jù)庫內(nèi)表單的代碼前弯,具體參考第一第3段蚪缀。原來代碼表單如果正確就保存進(jìn)數(shù)據(jù)庫秫逝,現(xiàn)在為了增加一個(gè)owner的值,save函數(shù)內(nèi)傳遞commit=False字段询枚,先保存到new_topic里违帆,設(shè)置好owner之后在保存。
new_entry函數(shù)也同樣進(jìn)行限制哩盲,只需要把check_topic_owner這個(gè)函數(shù)調(diào)用就行前方。至此,給這個(gè)項(xiàng)目創(chuàng)建一個(gè)賬戶管理系統(tǒng)就完成了廉油。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市苗傅,隨后出現(xiàn)的幾起案子抒线,更是在濱河造成了極大的恐慌,老刑警劉巖渣慕,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嘶炭,死亡現(xiàn)場離奇詭異,居然都是意外死亡逊桦,警方通過查閱死者的電腦和手機(jī)眨猎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來强经,“玉大人睡陪,你說我怎么就攤上這事∧淝椋” “怎么了兰迫?”我有些...
    開封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長炬称。 經(jīng)常有香客問我汁果,道長,這世上最難降的妖魔是什么玲躯? 我笑而不...
    開封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任据德,我火速辦了婚禮,結(jié)果婚禮上跷车,老公的妹妹穿的比我還像新娘棘利。我一直安慰自己,他們只是感情好姓赤,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開白布赡译。 她就那樣靜靜地躺著,像睡著了一般不铆。 火紅的嫁衣襯著肌膚如雪蝌焚。 梳的紋絲不亂的頭發(fā)上裹唆,一...
    開封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音只洒,去河邊找鬼许帐。 笑死,一個(gè)胖子當(dāng)著我的面吹牛毕谴,可吹牛的內(nèi)容都是我干的成畦。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼涝开,長吁一口氣:“原來是場噩夢啊……” “哼循帐!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起舀武,我...
    開封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤拄养,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后银舱,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瘪匿,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年寻馏,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了棋弥。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡诚欠,死狀恐怖顽染,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情聂薪,我是刑警寧澤家乘,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站藏澳,受9級(jí)特大地震影響仁锯,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜翔悠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一业崖、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蓄愁,春花似錦双炕、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春站超,著一層夾襖步出監(jiān)牢的瞬間荸恕,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來泰國打工死相, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留融求,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓算撮,卻偏偏與公主長得像生宛,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子肮柜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容