學習Django(1)

先把github鏈接放上來:
https://github.com/q100036q/python_demo_learning_logs

第一:安裝Django

在windows系統(tǒng)下安裝和使用Django很簡單语御,而且為了創(chuàng)建新的工程項目,可以創(chuàng)建一個虛擬的環(huán)境來獨立的編程席怪。
創(chuàng)建新的虛擬項目和安裝Django的流程如下:

1.新建一個工程路徑应闯,打開控制臺,切換到這個路徑下挂捻。

2.輸入下面代碼創(chuàng)建一個虛擬環(huán)境:

    python -m venv ll_env

3.激活虛擬環(huán)境碉纺,有兩種方法:第一是直接輸入:

    ll_env\Scripts\activate

上述代碼進行創(chuàng)建,第二種是刻撒,打開ll_env\Scripts文件夾骨田,按住shift點擊鼠標右鍵,打開命令窗口再把activate.bat拖進去声怔。這種方法適合第一次之后的打開态贤,就不用再命令行手動操作了。

4.創(chuàng)建并激活虛擬環(huán)境后醋火,就可安裝Django了悠汽,輸入下面代碼:

    pip install Django

第二:在Django中創(chuàng)建項目

1.創(chuàng)建項目路徑,用下面創(chuàng)建一個名為learning_log 的文件夾:

    django-admin.py startproject learning_log .

可是經過測驗芥驳,上面教程中的代碼無效柿冲,在網上只能找到另一種方案,輸入下面代碼:

    django-admin startproject learning_log .

最后的點不能省略兆旬,這個命令末尾的句點讓新項目使用合適的目錄結構假抄,manage.py這個文件會和ll_env文件夾同級,否則將會放進learning_log 文件夾下。
現(xiàn)在在ll_env文件夾同級目錄下慨亲,新出現(xiàn)了learning_log文件夾和manage.py文件。

2.創(chuàng)建數(shù)據(jù)庫宝鼓。使用manage.py文件進行數(shù)據(jù)庫的遷移指令刑棵,可以新建一個文件數(shù)據(jù)庫:

    python manage.py migrate 

這時候在ll_env文件夾同級目錄下又出現(xiàn)了一個名為db.sqlite3的數(shù)據(jù)庫文件。

3.查看項目是否能執(zhí)行愚铡。

    python manage.py runserver

上述代碼能夠運行一個服務器蛉签,并顯示出來url路徑,這時候我們可以通過瀏覽器輸入它來訪問這個本地服務器沥寥。

第三:創(chuàng)建一個應用程序

1.在第二步運行了一個服務器的情況下碍舍,重新再manage.py的路徑下打開一個命令行窗口,并執(zhí)行激活(第一步的第3條)邑雅。

2.執(zhí)行命令startapp片橡,它可以創(chuàng)建一個在同級路徑下的應用程序。

    python manage.py startapp learning_logs 

可以看到淮野,文件夾路徑下多了一個名為learning_logs的文件夾捧书,這個和之前第二步第1條創(chuàng)建的learning_log有很大的區(qū)別,具體看下圖:


2019226-172748.jpg

可以看到兩個文件夾內容完全不同骤星【桑可以這么理解,learning_log是我們控制中心洞难,存放一些配置相關的內容舆吮,而learning_logs是我們自己編寫程序的部分,用來管理數(shù)據(jù)队贱。

3.定義模型色冀,其實也就是創(chuàng)建各種各樣的類,來達到目的柱嫌,目前這個工程主要是用來保存數(shù)據(jù)呐伞,這里再models.py文件下定義兩個類,一個用于保存標題慎式,另一個保存內容伶氢,后者需要鏈接到前者。先看代碼:

#models.py   
from django.db import models
class Topic(models.Model):
  text = models.CharField(max_length = 200);
  date_added = models.DateTimeField(auto_now_add = True);

  def __str__(self):
    return self.text;

class Entry(models.Model):
  topic = models.ForeignKey(Topic,on_delete = models.CASCADE);
  text = models.TextField();
  date_added = models.DateTimeField(auto_now_add=True);

  class Meta:
    verbose_name_plural = 'entries';

   def __str__(self):
      if len(self.text) > 50:
          return self.text[:50] + '...';
      else:
          return self.text;

models.CharField是儲存字符或文本數(shù)據(jù)瘪吏,models.TextField類似癣防,但是是沒有長度限制,顯示在web上出來是一個文本框掌眠。
1)這里重點一個是on_delete = models.CASCADE這段代碼蕾盯,如果不加會報錯,主要是因為Django更新至2.0以上版本了蓝丙。
2)方法str() 告訴Django级遭,呈現(xiàn)條目時應顯示哪些信息望拖。
3)我們在Entry 類中嵌套了Meta 類。Meta 存儲用于管理模型的額外信息挫鸽,在這里说敏,它讓我們能夠設置一個特殊屬性,讓Django在需要時使用Entries 來表示多個條目丢郊。如果沒有這個類盔沫, Django將使用Entrys來表示多個條目。(這段還沒搞懂)枫匾。
4)Entry的第一個屬性topic 是一個ForeignKey 實例架诞。外鍵是一個數(shù)據(jù)庫術語,它引用了數(shù)據(jù)庫中的另一條記錄干茉;這些代碼將每個條目關聯(lián)到特定的主題谴忧。每個主題創(chuàng)建時,都給它分配了一個鍵(或ID)角虫。需要在兩項數(shù)據(jù)之間建立聯(lián)系時俏蛮,Django使用與每項信息相關聯(lián)的鍵。

4.激活模型上遥,要使用模型搏屑,必須讓Django將應用程序包含到項目中。這里需要用learning_log中的settings.py文件粉楚,并在INSTALLED_APPS里包含learning_logs內容:

#settings.py
INSTALLED_APPS = (
--snip--
'django.contrib.staticfiles',
# 我的應用程序
'learning_logs',
)

5.接下來辣恋,修改數(shù)據(jù)庫,使其能保存我們在models.py中定義的模型:

    python manage.py makemigrations learning_logs

接著進行數(shù)據(jù)庫的遷移模软,為我們的新模型去創(chuàng)建一個表:

    python manage.py migrate

6.Django管理網站伟骨,首先添加一個超級管理員的權限,這樣能在web上修改添加內容:

    python manage.py createsuperuser

按照提示輸入自己的信息即可燃异。
接著携狭,向管理網站注冊模型,之前定義的兩個模型回俐,在這里要進行注冊逛腿,注冊的代碼寫在admin.py中:

#admin.py      
from django.contrib import admin;
from learning_logs.models import Topic,Entry;

admin.site.register(Topic);
admin.site.register(Entry);

最后就可以訪問http://localhost:8000/admin/ ,輸入賬號密碼進入后臺仅颇,此時可以針對Topic和Entry進行編輯了单默,由于綁定外鍵的關系,一定要有一個Topic內容忘瓦,才能去添加Entry搁廓。

7.Django shell,可以使用shell來探索存儲在項目數(shù)據(jù)庫中的數(shù)據(jù)。

python manage.py shell

上面代碼可以運行到shell中境蜕,運行下面腳本蝙场,查看下我們數(shù)據(jù)庫的內容:

 from learning_logs.models import Topic
 topics = Topic.objects.all()
 for topic in topics:
    print(topic.id, topic)
  t = Topic.objects.get(id=1)
  t.text
  t.entry_set.all()

最后這條t.entry_set.all(),為通過外鍵關系獲取數(shù)據(jù)粱年,可使用相關模型的小寫名稱售滤、下劃線和單詞set。

8.遇到的問題:

1)每次修改模型(manage.py文件)逼泣,要重啟shell;
2)有的時候如果增加了新模型舟舒,要去修改admin.py增加新的注冊拉庶。
3)一般情況下,不需要重啟服務器秃励,但是如果一直不響應的情況下氏仗,可以ctrl+c關閉,在使用第二步的第3條重啟夺鲜。
4)關閉shall的方法:ctrl+z再回車即可皆尔。

第四:映射URL

簡單的說就是設置打開瀏覽器的頁面。這里先修改默認的主頁币励。

1.修改主目錄url內容慷蠕,打開項目主文件夾learning_log中的文件urls.py,這里添加內容:

#urls.py(learning_log/urls.py)
from django.contrib import admin;
from django.urls import path,include;
from django.conf.urls import url;

urlpatterns = [
  path('admin/', admin.site.urls),
  # path(r'',include('learning_logs.urls',namespace = 'learning_logs')),
  url(r'',include('learning_logs.urls',namespace = 'learning_logs'))
]

在Django1.11中路由函數(shù)為url()食呻,在Django2中路由函數(shù)改成了path()流炕,不過路由函數(shù)向下兼容,在Django2中同樣可以使用url()函數(shù)仅胞,這里列出兩種寫法每辟,注意引入對應的模塊,這里加載指向learning_logs.urls這個文件干旧,namespace只是為了和別的url作區(qū)分渠欺。

2.添加新目錄下的url,填寫現(xiàn)在我們需要在文件夾learning_logs中創(chuàng)建另一個urls.py文件椎眯,內容如下:

#urls.py
from django.conf.urls import url;
from . import views;
app_name='learning_logs'

urlpatterns = [
  url(r'^$',views.index,name = 'index'),
]

我們來看看正則表達式r'^$' 挠将。其中的r 讓Python將接下來的字符串視為原始字符串,而引號告訴Python正則表達式始于和終于何處编整。脫字符(^ )讓Python查看字符串的開頭捐名,而美元符號讓Python查看字符串的末尾∧只鳎總體而言镶蹋,這個正則表達式讓Python查找開頭和末尾之間沒有任何東西的URL。Python忽略項目的基礎URL(http://localhost:8000/),因此這個正則表達式與基礎URL匹配贺归。
url() 的第二個實參指定了要調用的視圖函數(shù)淆两。請求的URL與前述正則表達式匹配時,Django將調用views.index (這個視圖函數(shù)將在下一節(jié)編寫)拂酣。第三個實參將這個URL模式的名稱指定為index秋冰,讓我們能夠在代碼的其他地方引用它。每當需要提供到這個主頁的鏈接時婶熬,我們都將使用這個名稱剑勾,而不編寫URL。

3.編寫視圖內容赵颅,視圖函數(shù)接受請求中的信息虽另,準備好生成網頁所需的數(shù)據(jù),再將這些數(shù)據(jù)發(fā)送給瀏覽器饺谬,這個依據(jù)模板代碼來實現(xiàn)不同的效果捂刺,這里我們修改views.py文件:

#views.py
from django.shortcuts import render
def index(request):
    """學習筆記的主頁"""
    return render(request, 'learning_logs/index.html')

URL請求與我們剛才定義的模式匹配時,Django將在文件views.py中查找函數(shù)index() 募寨,再將請求對象傳遞給這個視圖函數(shù)族展。

4.編寫網頁模板。在文件夾learning_logs中新建一個文件夾拔鹰,并將其命名為templates仪缸。在文件夾templates中,再新建一個文件夾列肢,并將其命名為learning_logs腹殿。在最里面的文件夾learning_logs中,新建一個文件例书,并將其命名為index.html锣尉,再在這個文件中編寫如下代碼:

#index.html
<p>Learning Log</p>
<p>Learning Log helps you keep track of your learning, for any topic you'relearning about.</p>

這樣就完成了主頁的編輯。

5.幾個要點:

1)urls.py文件中的urlpatterns不能寫錯决采,否則會報錯自沧。
2)新創(chuàng)建的子文件夾的urls.py文件需要添加下面這行代碼,否則會報錯:

app_name='learning_logs'

這是因為之前定義了namespace屬性树瞭, [app_name]代表你的應用的名稱拇厢。
3)這篇代碼編寫完成后不用重啟服務器,在setting.py中設置了DEBUG = True晒喷,瀏覽器會自動刷新我們剛保存的代碼孝偎。但是,實際運用中DEBUG不能設置為true凉敲。

第五:創(chuàng)建其它網頁:

這段是對網頁和之前的數(shù)據(jù)綁定衣盾,把之前存入數(shù)據(jù)庫的內容展示出來寺旺。

1.模板繼承,可以創(chuàng)建一個父模板势决,讓其他模板(網頁代碼)都繼承它阻塑,可以方便統(tǒng)一修改。

下面果复,為了給幾個子網頁都添加一個統(tǒng)一的內容陈莽,父模板僅僅制作帶鏈接的標題,可以讓子模板點擊回到主頁虽抄。base.html內容如下:

#base.html
<p>
<a href="{% url 'learning_logs:index' %}">Learning Log</a>
<!--><a href="{% url 'learning_logs:topics' %}">Topics</a><-->
</p>
{% block content %}{% endblock content %}

有網頁制作相關知識的就知道<p>是一個段落標簽走搁,<a>是一個超鏈接標簽,href指向一個鏈接迈窟,這里{%%}是一個模板標簽私植,內容就指向了learning_logs下的index文件,即主頁菠隆。{% block content %}{% endblock content %}是一對占位符兵琳,具體內容由子模板指定狂秘。中間這段被注釋的代碼在后面顯示次級界面的時候要解開注釋『Ь叮現(xiàn)在重新編輯index.html文件,讓他繼承父模板base.html:

#index.html
{% extends "learning_logs/base.html" %}

{% block content %}
<p>Learning Log helps you keep track of your learning,for any topic you're learning about.</p>
{% endblock content %}

extends 表示繼承的路徑內容者春。占位符內容就是這個子模板獨有的內容破衔。它因為繼承自base.html,現(xiàn)在可以顯示如下:


2019228-172334.jpg

2.顯示主題頁面钱烟,為了增加新的下一級別的網頁晰筛,這里要去修改urls.py文件,增加了一行內容:

 #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'),
]

正則表達式中添加了topics/這一段拴袭,說明我們現(xiàn)在匹配的網址應該是:http://127.0.0.1:8000/topics/读第。其URL與該模式匹配的請求都將交給views.py中的函數(shù)topics() 進行處理。接下來拥刻,我們去這個文件中把它添加上:

#views.py
from django.shortcuts import render;

from .models import Topic;

def index(request):
    return render(request,'learning_logs/index.html');

def topics(request):
    topics = Topic.objects.order_by('date_added');
    context = {'topics':topics}
    return render(request,'learning_logs/topics.html',context)

這里是一個難點怜瞒,可能都已經忘記了之前我們做的操作了,這時候翻上去看第三步的第3段般哼,我們在models.py文件內寫下了Topic這個模型吴汪,并且定義了name和date_added這個屬性,order_by對其排序蒸眠,取出所有的值漾橙,然后保存為一個字典文件,并命名為context再通過render傳遞到topics.html里接收±憧ǎ現(xiàn)在當然是創(chuàng)建一個名為topics.html的頁面文件了:

#topics.html
{% extends "learning_logs/base.html" %}

{% block content %}
<p>Topics</p>
<ul>
    {% for topic in topics %}
    <li>
         <!-->注意霜运,這段在下面創(chuàng)建topic.html的時候放開注釋脾歇,為的是創(chuàng)建一個指向下一層級的超鏈接,并且將topic.id 傳遞到topic.html文件中
          <a href="{% url 'learning_logs:topic' topic.id %}">{{ topic }}</a>
         <-->
          {{ topic }}
    </li>
    {% empty %}
    <li>No topics have been added yet.</li>
    {% endfor %}
</ul>
{% endblock content %}

依照下圖觉渴,可以看出上面代碼說的到底是啥介劫,<ul><li>分別代表無序列表和列表項的標簽, {% for%}和 {% endfor %}用來當做一個for循環(huán)案淋,讀取views.py傳遞過來的內容座韵,并做成超鏈接虱疏,{{ topic }} 是將每一項名稱都顯示藐唠,不是使用一對,而是兩對舌缤,不然顯示的內容是:{ topic }瓣距。{% empty %}這個告訴了我們黔帕,這個循環(huán)內容為空的時候顯示什么東西。


2.jpg

這時候蹈丸,上面第五步的第1段中的注釋代碼要解開成黄。

3.顯示對應主題的內容。

之前逻杖,我們在定義文件的標題的同時也保存了相應的內容奋岁,這里我們點擊每個列表項之后,打開新的頁面去顯示它荸百。為了打開新的頁面闻伶,必須去urls.py增加新的配置:

#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'),
]

最后一行新增內容:在r'^$'直接加入了topics/(?P<topic_id>\d+)/這么一句正則表達式,作用就是匹配到http://localhost:8000/topics/1/這樣的URL够话,d+表示任意數(shù)字蓝翰,(?P)為命名捕獲,是捕獲內容儲存到topic_id中女嘲,這個是python專有的語法畜份。接下來還是根據(jù)這里設置的views.topic去views.py文件中新增topic函數(shù):

 #views.py
 from django.shortcuts import render;
 from .models import Topic;

def index(request):
    return render(request,'learning_logs/index.html');

def topics(request):
    topics = Topic.objects.order_by('date_added');
    context = {'topics':topics}
    return render(request,'learning_logs/topics.html',context)

def topic(request,topic_id):
    topic = Topic.objects.get(id = topic_id);
    entries = topic.entry_set.order_by('-date_added');
    context = {'topic':topic,'entries':entries}
    return render(request,'learning_logs/topic.html',context)

topic函數(shù)傳入剛剛捕獲到的參數(shù)topic_id,然后根據(jù)之前在shell里學習的方法欣尼,去數(shù)據(jù)庫中讀取數(shù)據(jù)爆雹,再通過date_added倒序排序,entry_set讀取出我們之前存入數(shù)據(jù)庫中的內容(忘記的話參考第三步的第7條)媒至,存進字典新增一項顶别。最后通過render一起傳給topic.html。

注意拒啰,這時候要把第五步第2段中topics.html文件中的注釋解開驯绎。

這時候創(chuàng)建這個文件:

#topic.html
{% extends "learning_logs/base.html" %}

{% block content %}
<p>Topics:{{topic}}</p>
<p>Entries:</p>
<ul>
    {% for entry in entries %}
    <li>
        <p>{{ entry.date_add|date:'M d,Y H:i'}}</p>
        <p>{{ entry.text|linebreaks }}</p>
    </li>
    {% empty %}
    <li>There are no entries for this topic yet.</li>
    {% endfor %}
</ul>
{% endblock content %}

這里其實很好理解,首先顯示Topics的值谋旦,這個在views.py里獲得了剩失。然后通過for循環(huán)讀取entries里面的內容屈尼,并且對應的格式化顯示,|符合是一個過濾器拴孤,linebreaks 作用是將包含換行符的長條目轉換為瀏覽器能夠理解的格式脾歧。這一切完成之后,顯示內容如下圖:


3.jpg

第六:總結

總得縷了一下演熟,django框架可以把數(shù)據(jù)庫鞭执,網頁結合起來,就不用和javaSE那樣分開做了芒粹,目前這個案例最傻的就是命名太相似兄纺,這樣要深刻理解代碼中寫的到底是指什么,代碼互相調用化漆,文件互相調用要深刻理解估脆,下面是我整理的調用流程:


4.jpg

下面是發(fā)現(xiàn)的一個容易出錯的問題,在<a>標簽頁內座云,'url'這個和之后的內容一定要分開疙赠,如果和下圖一樣連著,就會出現(xiàn)下面報錯k稀F匝簟!


6.jpg
7.jpg
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末贞谓,一起剝皮案震驚了整個濱河市限佩,隨后出現(xiàn)的幾起案子葵诈,更是在濱河造成了極大的恐慌裸弦,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件作喘,死亡現(xiàn)場離奇詭異理疙,居然都是意外死亡,警方通過查閱死者的電腦和手機泞坦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進店門窖贤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人贰锁,你說我怎么就攤上這事赃梧。” “怎么了豌熄?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵授嘀,是天一觀的道長。 經常有香客問我锣险,道長蹄皱,這世上最難降的妖魔是什么览闰? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮巷折,結果婚禮上压鉴,老公的妹妹穿的比我還像新娘。我一直安慰自己锻拘,他們只是感情好油吭,可當我...
    茶點故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著署拟,像睡著了一般上鞠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上芯丧,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天芍阎,我揣著相機與錄音,去河邊找鬼缨恒。 笑死谴咸,一個胖子當著我的面吹牛,可吹牛的內容都是我干的骗露。 我是一名探鬼主播岭佳,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼萧锉!你這毒婦竟也來了珊随?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤柿隙,失蹤者是張志新(化名)和其女友劉穎叶洞,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體禀崖,經...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡衩辟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了波附。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片艺晴。...
    茶點故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖掸屡,靈堂內的尸體忽然破棺而出封寞,到底是詐尸還是另有隱情,我是刑警寧澤仅财,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布狈究,位于F島的核電站,受9級特大地震影響满着,放射性物質發(fā)生泄漏谦炒。R本人自食惡果不足惜贯莺,卻給世界環(huán)境...
    茶點故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望宁改。 院中可真熱鬧缕探,春花似錦、人聲如沸还蹲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谜喊。三九已至潭兽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間斗遏,已是汗流浹背山卦。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留诵次,地道東北人账蓉。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像逾一,于是被迫代替她去往敵國和親铸本。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內容