django搭建web網(wǎng)站

首先我們聊一下django的前世今生司澎,據(jù)說03年的時(shí)候下面這幾家公司開始使用python構(gòu)建網(wǎng)站,
Lawrence Journal-World newspaper
Adrian Holovaty
Simon Willison
這幾家公司的工作性質(zhì)都有一個(gè)共同的特點(diǎn)就是每天需要不停的處理各類新聞事務(wù)栋豫、作品挤安,話說當(dāng)時(shí)編輯部門提出的需求變化之快讓技術(shù)部門毫無招架之力,所以django就在這年誕生了丧鸯,django與其快速開發(fā)的特性蛤铜,方便的model管理,MTV模型(model-template-view)成就了djano在python web領(lǐng)域的霸主地位丛肢,下面的演示將帶大家一起領(lǐng)略django的神奇魅力围肥。

步驟

1、環(huán)境準(zhǔn)備蜂怎,安裝django3.0版本,mysql驅(qū)動(dòng)
2穆刻、創(chuàng)建一個(gè)項(xiàng)目,并設(shè)置settings
3杠步、初始化數(shù)據(jù)庫氢伟,創(chuàng)建django超級(jí)用戶用于后臺(tái)model管理
4撰洗、創(chuàng)建一個(gè)app,在settings注冊(cè)app,在models.py創(chuàng)建模型,并在admin.py注冊(cè)model,生成遷移文件并同步到數(shù)據(jù)庫
5腐芍、app下views創(chuàng)建視圖層
6差导、app下創(chuàng)建urls路由配置文件,并為視圖層配置跳轉(zhuǎn)
7猪勇、app下創(chuàng)建templates/appName/結(jié)構(gòu)目錄设褐,并在目錄下創(chuàng)建視圖層對(duì)應(yīng)的html模板
8、效果展示
9泣刹、使用django view模板助析,簡化代碼量
10、static靜態(tài)資源使用

1椅您、安裝django3.0版本外冀,指定安裝源為國內(nèi)豆瓣源

pip install django==3.0 -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
pip install  -i http://pypi.douban.com/simple --trusted-host pypi.douban.com mysqlclient

django-admin startproject djangotest

2、settings.py設(shè)置

# 設(shè)置顯示語言
from django.utils.translation import gettext_lazy as _
LANGUAGES = [
    ('zh-Hans', _('Chinese')),
]
LANGUAGE_CODE = 'zh-Hans'

# 設(shè)置時(shí)區(qū)
TIME_ZONE = 'Asia/Shanghai'

# 設(shè)置數(shù)據(jù)庫掀泳,默認(rèn)使用sqlite3雪隧,這里使用mysql
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django',
        'USER': 'root',
        'PASSWORD': 'root',
        'HOST': '127.0.0.1',
        'PORT': '3306',
    }
}

3、初始化數(shù)據(jù)庫
3-1 在數(shù)據(jù)庫執(zhí)行下面命令創(chuàng)建django庫

 create database django default charset utf8;

3-2 在項(xiàng)目下執(zhí)行python manage.py migrate 同步django后臺(tái)管理的相關(guān)表


image.png

image.png

3-3 創(chuàng)建超級(jí)用戶用于django后臺(tái)登陸员舵,管理model

python manage.py createsuperuser
image.png

3-4 啟動(dòng)項(xiàng)目,訪問http://127.0.0.1:8000脑沿,http://127.0.0.1:8000/admin

python manage.py runserver
image.png

image.png

image.png

image.png

4、創(chuàng)建一個(gè)app马僻,在settings注冊(cè)app,在models.py創(chuàng)建模型,并在admin.py注冊(cè)model,生成遷移文件并同步到數(shù)據(jù)庫

4-1 創(chuàng)建一個(gè)民意調(diào)查的app,需求庄拇,我們需要對(duì)網(wǎng)友關(guān)注的問題進(jìn)行網(wǎng)絡(luò)投票,一個(gè)問題對(duì)應(yīng)多種答案韭邓,每個(gè)網(wǎng)民可以對(duì)其中的一個(gè)答案進(jìn)行投票
python manage.py startapp polls

image.png

4-2 在settings.py INSTALLED_APPS增加polls app

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'polls.apps.PollsConfig',
]

4-3 models.py創(chuàng)建model模型

from django.db import models

# 繼承Model措近,django會(huì)自動(dòng)識(shí)別并在數(shù)據(jù)庫創(chuàng)建該表
class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    
    # 用于django后臺(tái)顯示該字段
    def __str__(self):
        return self.question_text

class Choice(models.Model):
    # 一對(duì)多關(guān)系,刪除question時(shí)女淑,對(duì)應(yīng)的choice也會(huì)刪除
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

    def __str__(self):
        return self.choice_text

4-4 admin.py注冊(cè) model

from django.contrib import admin
from .models import Question, Choice
admin.site.register(Question)
admin.site.register(Choice)

4-5 生成遷移文件瞭郑,并同步到數(shù)據(jù)庫

python manage.py makemigrations
python manage.py migrate

image.png

image.png

4-6 后臺(tái)可以看到已更新剛注冊(cè)的model


image.png

4-7 增加幾個(gè)quesiton,并對(duì)question設(shè)置幾個(gè)選項(xiàng)


image.png

image.png

image.png

image.png

image.png

5诗力、polls/views.py創(chuàng)建視圖層

from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect
from .models import Question, Choice
from django.urls import reverse

# 獲取最近相關(guān)的5個(gè)問題
def index(request):
    latest_question_list = Question.objects.order_by('-pub_date')[:5]
    context = {'latest_question_list': latest_question_list}
    return render(request, 'polls/index.html', context)

# 投票頁面
def detail(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    return render(request, 'polls/detail.html', {'question': question})

# 投票處理
def vote(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    try:
        # POST請(qǐng)求的key需要與detail.html input name屬性保持一致
        selected_choice = question.choice_set.get(pk=request.POST['choice'])
    except(KeyError, Choice.DoesNotExist):
        return render(request, 'polls/detail.html',{
            'question':question,
            'error_message': "You didn't select a choice"
        })
    else:
        selected_choice.votes += 1
        selected_choice.save()
        return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))

# 投票結(jié)果展示
def results(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    return render(request, 'polls/results.html', {'question':question})

6凰浮、app下創(chuàng)建urls.py路由配置文件我抠,并為視圖層配置跳轉(zhuǎn)

from django.urls import path
from . import views

# app命名空間苇本,django一個(gè)項(xiàng)目包含n個(gè)app,使用命名可以可以對(duì)url進(jìn)行分類
app_name = 'polls'
urlpatterns =  [
    path('', views.index, name='index'),
    path('<int:question_id>/', views.detail, name='detail'),
    path('<int:question_id>/vote/', views.vote, name='vote'),
    path('<int:question_id>/results/', views.results, name='results'),
]

項(xiàng)目路由配置

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('polls/', include('polls.urls')),
]
image.png

7菜拓、app下創(chuàng)建templates/appName/結(jié)構(gòu)目錄瓣窄,并在目錄下創(chuàng)建視圖層對(duì)應(yīng)的html模板,下面的是django模板的固定寫法.

image.png

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{% if latest_question_list %}
    <ul>
        {% for question in latest_question_list %}
            <li> <a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a> </li>
        {% endfor %}
    </ul>
{% else %}
    <p> don't have resources </p>
{% endif %}
</body>
</html>

detail.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1> {{ question.question_text }} </h1>
{% if error_message %} <p> <strong> {{ error_message }} </strong> </p> {% endif %}
<form action="{% url 'polls:vote' question.id %}" method="post">
    {% csrf_token %}
    <ul>
        {% for choice in question.choice_set.all %}
            <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}">
            <label for="choice{{ forloop.counter }}"> {{ choice.choice_text }} </label>
        {% endfor %}
    </ul>
    <input type="submit" value="Vote">
</form>

</body>
</html>

results.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1> {{ question.question_text }} </h1>

<ul>
    {% for choice in question.choice_set.all %}
        <li> {{ choice.choice_text }} -- {{ choice.votes }} </li>
    {% endfor %}
</ul>
<a href="{% url 'polls:vote' question.id %}"> Vote again? </a>
</body>
</html>

8、效果展示

index首頁


image.png

投票頁面


image.png

結(jié)果展示頁面


image.png

9纳鼎、django為單個(gè)model或model list集合提供了模板俺夕,對(duì)于上面的index,detail,results裳凸,都是查詢model或model集合,下面對(duì)這些view進(jìn)行簡化

9-1 修改views.py, urls.py如下

views.py
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.shortcuts import get_object_or_404, render
from django.views import generic
from .models import Question, Choice

class IndexView(generic.ListView):
    template_name = 'polls/index.html'
    context_object_name = 'latest_question_list'

    def get_queryset(self):
        return Question.objects.order_by('-pub_date')[:5]

# django DetailView模板 默認(rèn)返回的是<app name>/<model name>_detail.html,你甚至可以不指定template_name劝贸,
# 只要你按照相應(yīng)的規(guī)則創(chuàng)建html
class DetailView(generic.DetailView):
    model = Question
    template_name = 'polls/detail.html'

class ResultsView(generic.DetailView):
    model = Question
    template_name = 'polls/results.html'

def vote(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    try:
        # POST請(qǐng)求的key需要與detail.html input name屬性保持一致
        selected_choice = question.choice_set.get(pk=request.POST['choice'])
    except(KeyError, Choice.DoesNotExist):
        return render(request, 'polls/detail.html',{
            'question':question,
            'error_message': "You didn't select a choice"
        })
    else:
        selected_choice.votes += 1
        selected_choice.save()
        return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))


urls.py
from django.urls import path
from . import views

app_name = 'polls'

# 這里使用主鍵代替上面的question_id
urlpatterns = [
    path('', views.IndexView.as_view(), name='index'),
    path('<int:pk>/', views.DetailView.as_view(), name='detail'),
    path('<int:pk>/results/', views.ResultsView.as_view(), name='results'),
    path('<int:question_id>/vote/', views.vote, name='vote'),
]


10姨谷、django給我們每一個(gè)app提供了靜態(tài)資源的管理,創(chuàng)建<app name>/static/<app name>/style.css


image.png

index.html引用樣式

{% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'polls/style.css' %}">
image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末映九,一起剝皮案震驚了整個(gè)濱河市梦湘,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌件甥,老刑警劉巖捌议,帶你破解...
    沈念sama閱讀 218,036評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異引有,居然都是意外死亡瓣颅,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門譬正,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宫补,“玉大人,你說我怎么就攤上這事曾我∈匚剑” “怎么了?”我有些...
    開封第一講書人閱讀 164,411評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵您单,是天一觀的道長斋荞。 經(jīng)常有香客問我,道長虐秦,這世上最難降的妖魔是什么平酿? 我笑而不...
    開封第一講書人閱讀 58,622評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮悦陋,結(jié)果婚禮上蜈彼,老公的妹妹穿的比我還像新娘。我一直安慰自己俺驶,他們只是感情好幸逆,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著暮现,像睡著了一般还绘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上栖袋,一...
    開封第一講書人閱讀 51,521評(píng)論 1 304
  • 那天拍顷,我揣著相機(jī)與錄音,去河邊找鬼塘幅。 笑死昔案,一個(gè)胖子當(dāng)著我的面吹牛尿贫,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播踏揣,決...
    沈念sama閱讀 40,288評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼庆亡,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了捞稿?” 一聲冷哼從身側(cè)響起身冀,我...
    開封第一講書人閱讀 39,200評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎括享,沒想到半個(gè)月后搂根,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,644評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡铃辖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評(píng)論 3 336
  • 正文 我和宋清朗相戀三年剩愧,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片娇斩。...
    茶點(diǎn)故事閱讀 39,953評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡仁卷,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出犬第,到底是詐尸還是另有隱情锦积,我是刑警寧澤,帶...
    沈念sama閱讀 35,673評(píng)論 5 346
  • 正文 年R本政府宣布歉嗓,位于F島的核電站丰介,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏鉴分。R本人自食惡果不足惜哮幢,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望志珍。 院中可真熱鬧橙垢,春花似錦、人聲如沸伦糯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽敛纲。三九已至喂击,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間载慈,已是汗流浹背惭等。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留办铡,地道東北人辞做。 一個(gè)月前我還...
    沈念sama閱讀 48,119評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像寡具,于是被迫代替她去往敵國和親秤茅。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評(píng)論 2 355