Django入門課程一-創(chuàng)新互聯(lián)

準備環(huán)境

1、安裝Django

創(chuàng)新互聯(lián)公司"三網(wǎng)合一"的企業(yè)建站思路。企業(yè)可建設擁有電腦版、微信版、手機版的企業(yè)網(wǎng)站。實現(xiàn)跨屏營銷,產(chǎn)品發(fā)布一步更新,電腦網(wǎng)絡+移動網(wǎng)絡一網(wǎng)打盡,滿足企業(yè)的營銷需求!創(chuàng)新互聯(lián)公司具備承接各種類型的網(wǎng)站設計、做網(wǎng)站項目的能力。經(jīng)過10年的努力的開拓,為不同行業(yè)的企事業(yè)單位提供了優(yōu)質(zhì)的服務,并獲得了客戶的一致好評。
$ pip install django==2.2.0
$ pip list
Package          Version
---------------- -------
backcall         0.1.0  
decorator        4.4.0  
Django           2.2    

$ python -m django --version
2.2

2、安裝 mysqlclient
$ pip3 install mysqlclient

如果報錯,請參考:https://blog.51cto.com/qiangsh/2422115

web框架的設計邏輯

1:用戶打開一個網(wǎng)址的步驟

從用戶角度分析一個框架(網(wǎng)站)都需要那些零件

經(jīng)典的MVC(MTV)框架是怎么來的呢?

  • 用戶輸入網(wǎng)址是哪里定義的呢?——URL
  • 用戶兩種訪問模式讀(get)/寫(post),誰來處理?——view(control)
  • view處理的需要數(shù)據(jù)在哪存著的呢?——model
  • view處理完畢,用戶請求看到的頁面是誰渲染的呢?——template(view)

2:以此設計邏輯分析django框架

首先創(chuàng)建django項目,查看下項目的目錄結構

使用 django-admin 來創(chuàng)建 devops 項目:

django-admin.py startproject devops

查看項目的目錄結構:

$ tree devops/
├── devops       
│?? ├── __init__.py
│?? ├── settings.py
│?? ├── urls.py
│?? └── wsgi.py
├── manage.py

目錄說明:

  • devops: 項目的容器。
  • manage.py: 一個實用的命令行工具,可讓你以各種方式與該 Django 項目進行交互。
  • devops/init.py: 一個空文件,告訴 Python 該目錄是一個 Python 包。
  • devops/settings.py: 該 Django 項目的設置/配置。
  • devops/urls.py: 該 Django 項目的 URL 聲明; 一份由 Django 驅(qū)動的網(wǎng)站"目錄"。
  • devops/wsgi.py: 一個 WSGI 兼容的 Web 服務器的入口,以便運行你的項目。

2.1:訪問URL——為啥訪問 http://ip/admin就訪問到了管理后臺

# URL總入口
$ cat  devops/urls.py 
from django.contrib import admin
from django.urls import path

urlpatterns = [
    # 訪問admin的請求交給了admin.site.urls處理,而admin是django自帶的APP  
    path('admin/', admin.site.urls), 
]

# devops項目總配置文件
$ cat devops/settings.py
……
# Django自帶的APP都已經(jīng)在這里注冊好了,我們自己定義的app也得在這里注冊
INSTALLED_APPS = [
    'django.contrib.admin',     
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'hello.apps.HelloConfig',             # 添加此行
]
……

# 這些django自動的APP在哪呢?
$ ls ~/env3/lib/python3.6/site-packages/django/contrib/
admin  admindocs  auth  contenttypes  flatpages  gis  humanize  __init__.py  messages  postgres  __pycache__  redirects  sessions  sitemaps  sites  staticfiles  syndication

# 找到admin這個APP的url
$ vim  ~/env3/lib/python3.6/site-packages/django/contrib/admin/sites.py
……
    def urls(self):
        return self.get_urls(), 'admin', self.name
……

2.2:用戶發(fā)出的請求是數(shù)來處理的呢

URL已經(jīng)將用戶請求帶到了admin的內(nèi)部。用戶訪問admin后臺其實提交了兩個操作,第一是get請求admin頁面,admin給了一個列表框,要求填寫用戶名密碼;第二個是post請求是把用戶密碼提交給admin,那么這兩個請求是誰來處理的呢——view

# admin app的view目錄下編寫應對用戶請求的各種邏輯,源碼可自行查看
$ ls  ~/env3/lib/python3.6/site-packages/django/contrib/admin/views/
autocomplete.py  decorators.py  __init__.py  main.py

2.3:數(shù)據(jù)存在哪里?數(shù)據(jù)表結構哪里定義的呢?
vim ~/env3/lib/python3.6/site-packages/django/contrib/admin/models.py

2.4:用戶看的頁面各種樣式在哪里定義的呢?

$ ls    ~/env3/lib/python3.6/site-packages/django/contrib/admin/templates/admin/
404.html        auth              change_form_object_tools.html  date_hierarchy.html                filter.html         login.html           prepopulated_fields_js.html
500.html        base.html         change_list.html               delete_confirmation.html           includes            object_history.html  search_form.html
actions.html    base_site.html    change_list_object_tools.html  delete_selected_confirmation.html  index.html          pagination.html      submit_line.html
app_index.html  change_form.html  change_list_results.html       edit_inline                        invalid_setup.html  popup_response.html  widgets

Django起步

1、創(chuàng)建工程
django-admin.py startproject devops

2、創(chuàng)建一個APP(應用)

Django框架的組織架構:一個項目(Project)下可以有多個應用(APP),每個應用下面都五臟俱全的MTV模塊(就是以py結尾的文件),每個模塊各司其職。

qiangsh@Dream ~/D/P/5/Django_day1> cd devops/
qiangsh@Dream ~/D/P/5/D/devops> python manage.py startapp hello
qiangsh@Dream ~/D/P/5/D/devops> tree hello
hello
├── admin.py               # 后臺管理文件
├── apps.py                # app命名文件
├── __init__.py            # 初始化文件,有他表示這是一個包
├── migrations             # 數(shù)據(jù)遷移文件
│   └── __init__.py
├── models.py              # 模型文件
├── tests.py
├── urls.py                # 定義路由,默認沒有,自己加的
└── views.py               # 邏輯處理,即控制器

2.1:全局配置文件中注冊新創(chuàng)建的APP

$ cat devops/settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'hello.apps.HelloConfig',     # 添加此行
]

注釋下面一行,解決權限問題

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    #'django.middleware.csrf.CsrfViewMiddleware',  #注釋此行,解決跨域
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

2.2:編寫處理邏輯代碼(控制器)

$ cat hello/views.py

# Create your views here.
from django.shortcuts import render
from django.http import HttpResponse,QueryDict

# 練習一
# def index(request):
#     return HttpResponse("<p>Hello World,Hello, Django</p>")

# 練習二
# 位置參數(shù)的接收方法---函數(shù)中的參數(shù)和URL中的位置一一對應(嚴重依賴參數(shù)順序且代碼可讀性不好,不推薦)
def index(request,year=2018,month=8):
    # 普通參數(shù)的接受方法
    # 方法一、設置默認值的方式獲取數(shù)據(jù)更優(yōu)雅
    year = request.GET.get("year","2019")
    # 方法二、直接獲取數(shù)據(jù),沒有傳值會報錯,不建議使用
    month = request.GET["month"]

    return HttpResponse("year is %s,month is %s" %(year,month))

# 關鍵字傳參數(shù)(?<參數(shù)名>參數(shù)類型)——視圖中直接通過參數(shù)名獲取值(最常用)
def index2(request,**kwargs):
    # 請求參數(shù)接收,默認為GET請求,通過method判斷POST請求
    if request.method == "POST":
        print(request.scheme)  # http
        #print(request.method)    #POST
        print(request.body)    #b'year=2019&month=11'
        #print(type(request.body))
        print(QueryDict(request.body).dict())   #{'year': '2018', 'month': '08'}
        #print(type(QueryDict(request.body).dict()))
        print(request.POST)    #<QueryDict: {'year': ['2018'], 'month': ['08']}>
        print(type(request.POST))    #<class 'django.http.request.QueryDict'>

        data = request.POST
        year = data.get('year',2018)
        month = data.get('month',8)
    else:
        print(request)
        print(request.method)
        print(request.META)
        print(request.body)
        print(kwargs)
        year = kwargs.get('year',2018)
        month = kwargs.get('month',8)
    return HttpResponse("year is %s,month is %s" %(year,month))

def user(request,**kwargs):
    if request.method == "POST":
        pass
    else:
        user = {'name':'qsh','age':'18'}
    return render(request,'index.html',{'user':user})

2.3:編寫提供給用戶訪問的路由URL

URL的設計比較優(yōu)雅的方式:APP自己定義自己的url,然后在全局統(tǒng)一入口的url文件中引入即可

#設計自己的url, 用戶訪問/hello就會把請求發(fā)給views模塊中的index方法

$ cat hello/urls.py       # 系統(tǒng)沒有,需要自己建立

from django.urls import path,re_path
from . import views

urlpatterns = [
    # 2.3.1:普通傳參url基本和無參數(shù)一樣
    # 請求方式 http://127.0.0.1:8000/hello/hello/?year=2019&month=10
    path('index/', views.index, name='index'),        
    path('hello/',views.index2, name='index'), 
    # URL中每個位置數(shù)值和view中定義的參數(shù)順序一一對應(代碼可讀性不好,不推薦)

    # 2.3.2:位置匹配
    # 請求方式 http://127.0.0.1:8000/hello/hello/2019/08/
    re_path('hello/([0-9]{4})/([0-9]{2})/', views.index2, name='index2'),

    # 2.3.3:關鍵字匹配(最優(yōu)雅)  (?<參數(shù)名>參數(shù)類型)??視圖中直接通過參數(shù)名獲取值(最常用)
    re_path('user/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/', views.user, name='user'),
]

#在統(tǒng)一訪問url入口將hello的url引入進來(注冊子app的url)

$ cat devops/urls.py

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

urlpatterns = [
    path('admin/', admin.site.urls),
    path('hello/',include('hello.urls'),name="hello"),
]

# 總入口文件又多了一層路徑,所以最終的訪問路徑為 http://ip:8000/hello/<app_url>/

#最終路徑如下

$ tree
.
├── devops               # devops工程自動的全局app
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py         # 全局路由入口 
│   └── wsgi.py
├── hello               # 自己創(chuàng)建的app
│   ├── admin.py
│   ├── apps.py
│   ├── __init__.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   ├── urls.py    # 每個app自定義的路由入口,需要注冊
│   └── views.py
└── manage.py

3 directories, 13 files

3、啟動工程

python manage.py runserver 0.0.0.0:8000

小結

以上這個小栗子其實只用到了MTV中的View以及URL(url是view的指引,這兩個會一起出現(xiàn),統(tǒng)稱為V),數(shù)據(jù)庫和模板都沒用上,故而體驗不好,功能也簡單,好歹是跑通了。接下來一個完整的項目。在此之前把V和URL的最佳實戰(zhàn)知識學習下

MTV之視圖(URL&&View)

hello的小栗子主要實現(xiàn)了用戶發(fā)起請求,然后Django根據(jù)用戶發(fā)起的url路徑找到對應的處理函數(shù),然后將內(nèi)容簡單返回而已。但現(xiàn)實中用戶的請求可不是這么簡單。用戶都會有那些請求呢,大致可以分為兩類讀和寫,讀有帶參數(shù)和不帶參數(shù)兩種場景,寫肯定是帶參數(shù)了
Django的MTV模式本質(zhì)上和MVC是一樣的,也是為了各組件間保持松耦合關系,只是定義上有些許不同

Django的MTV分別是值:

  • M 代表模型(Model):負責業(yè)務對象和數(shù)據(jù)庫的關系映射(ORM)。
  • T 代表模板 (Template):負責如何把頁面展示給用戶(html)。
  • V 代表視圖(View):負責業(yè)務邏輯,并在適當時候調(diào)用Model和Template。
    除了以上三層之外,還需要一個URL分發(fā)器,它的作用是將一個個URL的頁面請求分發(fā)給不同的View處理,View再調(diào)用相應的Model和
    Template,MTV的響應模式如下所示:
    1. Web服務器(中間件)收到一個http請求
    2. Django在URLconf里查找對應的視圖(View)函數(shù)來處理http請求
    3. 視圖函數(shù)調(diào)用相應的數(shù)據(jù)模型來存取數(shù)據(jù)、調(diào)用相應的模板向用戶展示頁面
    4. 視圖函數(shù)處理結束后返回一個http的響應給Web服務器
    5. Web服務器將響應發(fā)送給客戶端
      Django入門課程一

4、添加html文件
#添加模板目錄 'DIRS': []

$ cat devops/settings.py

TEMPLATES = [
    {
        # 模板引擎,翻譯給前端展示
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        # 模板目錄,當前目錄下創(chuàng)建templates
        'DIRS': [BASE_DIR+"/templates"],
        # 如果統(tǒng)一目錄沒有,就在app自己目錄查找
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

#配置解釋
* BACKEND 是一個指向?qū)崿F(xiàn)了Django模板后端API的模板引擎類的帶點的Python路徑。內(nèi)置的后有django.template.backends.django.DjangoTemplates 和 django.template.backends.jinja2.Jinja2.兩個模板差不多
* DIRS 定義了一個目錄列表,模板引擎按列表順序搜索這些目錄以查找模板源文件。默認會先找templates目錄
* APP_DIRS 告訴模板引擎是否應該進入每個已安裝的應用中查找模板。每種模板引擎后端都定義了一個慣用的名稱作為應用內(nèi)部存放模板的子目錄名
qiangsh@Dream ~> cd devops
qiangsh@Dream ~/devops> mkdir templates/

qiangsh@Dream ~/devops> cat index.html

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
   <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<title>python訓練營</title>
<head>
<body >
myname is {{ user.name }}, age is {{ user.age }}

</body>
</html>

5、瀏覽器訪問
5.1:帶參數(shù)的讀——get

  • 用戶請求帶參數(shù)的url
    # 普通參數(shù)
    http://127.0.0.1:8000/hello/index/?year=2019&month=10

    Django入門課程一

    # 位置參數(shù)
    http://127.0.0.1:8000/hello/hello/2018/01/

    Django入門課程一

5.2:帶參數(shù)的寫——post

#shell終端,模擬django表單POST提交數(shù)據(jù)
curl -X POST http://127.0.0.1:8000/hello/hello/ -d 'year=2019&month=11'

Django入門課程一
Django入門課程一

http://127.0.0.1:8000/hello/user/2019/08/
Django入門課程一

6、QueryDict

通過上面演示我們知道無論GET/POST請求,接受參數(shù)的數(shù)據(jù)類型都是QueryDict。QueryDict到底做了什么事情呢

在HttpRequest 對象中,GET 和POST 屬性是django.http.QueryDict 的實例,它是一個自定義的類似字典的類,用來處理同一個鍵帶有多個值。無論使用GET,POST方式,他們最終都是通過QueryDict方法對傳入的參數(shù)進行處理

# QueryDict常用方法

>>> QueryDict('a=1&a=2&c=3')            # 對用戶請求的數(shù)據(jù)處理
<QueryDict: {'a': ['1', '2'], 'c': ['3']}>

>>> QueryDict.get(key, default=None)    # 獲取數(shù)據(jù)

>>> q = QueryDict('a=1&a=2&a=3')
>>> q.lists()
[('a', ['1', '2', '3'])]

>>> q = QueryDict('a=1&b=3&c=5')
>>> q.dict()
{'a': '1','b':'3','c':'5'}

表格練習

1、修改邏輯代碼

$ cat hello/views.py 

def user(request,**kwargs):
    if request.method == "POST":
        pass
    else:
        user = {'name':'qsh','age':'18'}

        title = "devops"
        books = ['python','java','php','web']
        people = {'name':'qsh','age':18,'sex':'male'}
        products = [{'pid': 1, 'name': 'iphone'}, {'pid': 2, 'name': 'computer'}, {'pid': 3, 'name': 'TV'}]

    return render(request,'index.html',{'title':title,'books':books,'people':people,'user':user,'products':products})

2、修改html頁面

$ cat templates/index.html

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
   <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<title>{{title}}</title>
<head>
<body >   

 {# 接受列表的第N個值,很low不推薦 #}
<li>{{books.0}}</li>    
<li>{{books.1}}</li>
<li>{{books.2}}</li>
<li>{{books.3}}</li>

{# for循環(huán)標簽 ,渲染books列表 #}
{% for book in books %}
<li>{{book}}</li>
{% endfor %}

{# 接受字典中的定義的值 #}
<div >hello my name is {{people.name}} </br>
  my age is {{ people.age }} and I am {{ people.sex }}
</div>

{# if標簽使用,判斷user是否存在 #}
{% if people %}
    <li>name:{{people.name}}</li>
{% else %}
    用戶不存在
{% endif %}

{# for循環(huán)輸出字典里所有的key,value #}
{% for k,v in people.items %}
<li>{{k}}-->{{v}}</li>
{% endfor %}

{# 列表頁展示 #}
{% for product in products %}
  <li>ID:{{product.pid}},Name:{{product.name}}</li>
{% endfor %}

{# 列表頁展示,表格輸出 #}
<table border="1">
<thead>  {# 定義表格的表頭 #}
      <tr>    {# 行 #}
          <th>ID</th>     {# 表頭單元格 - 包含表頭信息 #}
          <th>商品名</th>
      </tr>
</thead>
<tbody>
    {% for product in products %}
    <tr>
        <td> {{product.pid}} </td>       {# 標準單元 - 包含數(shù)據(jù) #}
        <td> {{product.name}} </td>
    </tr>
    {% endfor %}
</tbody>
</table>

</body>
</html>

3、瀏覽器訪問
http://127.0.0.1:8000/hello/user/2019/08/
Django入門課程一

表單練習

1、修改邏輯代碼

$ cat hello/views.py

#添加模塊
from django.http import HttpResponse, QueryDict, HttpResponseRedirect
from django.shortcuts import render
from django.urls import reverse

#新建登錄函數(shù)
def login(request, **kwargs):
    data = ""
    if request.method == "POST":
        print(request.POST)
        print(QueryDict(request.body).dict())
        username = request.POST.get('username','qsh')
        passwd = request.POST.get('password','123456')
        if username == "admin" and passwd == "123456":
            # data = "welcome you %s" % username
            return HttpResponseRedirect(reverse("hello:user"))
            # return HttpResponseRedirect("/hello/hello/")
        else:
            data = "your passwd or username is wrong,plaeace again"
    return render(request, 'login.html', {'data':data})

2、創(chuàng)建登錄html

$ cat templates/login.html

<html>
<body>
    <!--登陸表單-->
    <form action="{% url 'hello:login' %}" method="post">
         <!--用戶名-->
        <input name="username" type="text"  placeholder="用戶名"> </br>
         <!--密碼-->
        <input name="password" type="password"  placeholder="密碼"> </br>
        <button type="submit">登錄</button>
    </form>
    {% if data %}
    <h2>{{ data }}</h2>
    {% endif %}
</body>

</html>

3、路由

$ cat hello/urls.py

from django.urls import path,re_path
from . import views

app_name = 'hello'
urlpatterns = [
    path('index/', views.index, name='index'),
    path('hello/',views.index2, name='hello'),
    path('login/',views.login, name='login'),
    path('index2/',views.user, name='user'),
    re_path('hello/([0-9]{4})/([0-9]{2})/', views.index2, name='index2'),
    re_path('user/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/', views.user, name='user'),
]

4、瀏覽器訪問
http://127.0.0.1:8000/hello/login/
用戶名密碼錯誤,效果如下。
Django入門課程一

輸入正確 跳轉(zhuǎn)http://127.0.0.1:8000/hello/index2/
Django入門課程一

頁面美化

模板template如何接收View的各種數(shù)據(jù)類型并渲染已經(jīng)完成,但頁面還是不夠美麗,就得引出前端內(nèi)容了——Bootstrap(HTML/CSS/Jquery)

學習網(wǎng)站:
https://v3.bootcss.com/
https://v3.bootcss.com/css/

另外有需要云服務器可以了解下創(chuàng)新互聯(lián)cdcxhl.cn,海內(nèi)外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。

網(wǎng)站題目:Django入門課程一-創(chuàng)新互聯(lián)
轉(zhuǎn)載來于:http://bm7419.com/article44/ihiee.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供響應式網(wǎng)站、定制網(wǎng)站、建站公司、小程序開發(fā)、ChatGPT品牌網(wǎng)站設計

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站建設