目錄
- 1. 回顧知識
- 1.1 新增工程
- 1.2 創建新的APP
- 1.3 注冊APP
- 1.4 撰寫URL和VIEW
- 1.5 驗證結果如下:
- 2. 基本概念
- 2.1 專業術語
- 2.2 MTV之視圖
- 2.2.1 request物件
- 2.2.2 Respone物件
- 2.2.3 GET請求
- 2.2.4 POST請求
- 2.2.5 QueryDict介紹
- 3. MTV之模板
- 3.1 模板繼承
- 3.1.1 常規手段
- 3.1.2 模板繼承
- 3.1 模板繼承
- 4. Template模板過濾器
- 4.1 Django自帶常用過濾器
- 4.2 自定義模板標簽和過濾器
- 5. 模型Model基礎
- 5.1 模型概念
- 5.1.1 常用欄位型別
- 5.1.2 常用欄位引數
- 5.1 模型概念
- 6. 建模及同步
- 6.1 設計一個簡單的模型
- 6.2 將模型同步到資料庫
- 7. ORM實作簡單的增刪改查
- 7.1 ORM概念
- 7.2 增 | 刪 | 改 | 查
- 7.2.1 增加資料
- 7.2.2 洗掉洗掉
- 7.2.3 修改資料
- 7.2.4 查看資料
- 8. 打通MTV
- 8.1 創建模型
- 8.2 創建視圖view
- 8.3 創建模板
- 8.4 創建路由視圖URL
- 8.5 效果圖如下:
Hello, 各位,我回來了,大家別以為我消失了,我還是在的...
最近忙于家里重要事情,不能定期及時更新,請包含...
忙里挑一,我還是在后臺默默的碼了幾篇文章,前提要保證下質量,才能發出來,哈哈!不然...嘿嘿
大家搬好小板凳了,前方的真的高能,文章篇幅有點多,一步一步來...
跟著我走,簡單學起來...
1. 回顧知識
上一篇文章已經教會了大家怎么安裝Django和簡單的配置,相信大家應該早就學會了,那么我們在回憶一下吧,懂的同學可跳過這章節,
1.1 新增工程
django-admin startproject <自定義工程名稱>
(py369) [python@localhost Python]$ django-admin startproject devops
1.2 創建新的APP
python manage.py startapp <自定義APP名稱>
(py369) [python@localhost devops]$ python manage.py startapp hello
1.3 注冊APP
在devops->settings.y里面t添加:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# 第一種方式
'hello.apps.HelloConfig',
# 第二種方式,直接寫hello也行
'hello',
]
1.4 撰寫URL和VIEW
在devops下的主路由urls.py:
from django.contrib import admin
from django.urls import path,include
from views import index
urlpatterns = [
path('admin/', admin.site.urls),
path('', index.index),
# 引導到hello下的路由URL(也叫子路由)
path('hello/', include('hello.urls'))
]
在hello下的子路由urls.py:
from django.urls import path
from hello import view
app_name = 'hello'
urlpatterns = [
# 普通url引數
path('', view.index, name='index'),
hello下的view.py代碼:
from django.http import HttpResponse
def index(request):
return HttpResponse('hello django')
1.5 驗證結果如下:

2. 基本概念
2.1 專業術語
MTV簡寫:
-
M:model,這個是對應資料庫的,簡單理解就是對應資料庫的表,
-
T:template,這個對應的是HTML模板,前端渲染用的,
-
V:view,這個對應的是后臺python執行腳本了,
通俗的一句話:用戶發送http請求,匹配url后執行view腳本回傳模板template,用戶看到了網頁的展示效果(渲染),
2.2 MTV之視圖
2.2.1 request物件

2.2.2 Respone物件

下面詳細介紹下...
2.2.3 GET請求
-
GET請求,不帶引數
網頁輸入這樣的格式,是
不帶引數:https://192.168.8.130:8888/hello備注:如上面演示的就是不帶引數,
-
GET請求,?+引數
比較常用的方式
?+引數在瀏覽器輸入如下地址:
http://192.168.8.130:8888/hello/?year=2020&month=09&day=02說明: 引數:
yearmonthday網址匹配到路由
hello/url.py的配置規則from django.urls import path from hello import view app_name = 'hello' urlpatterns = [ # 普通引數 path('', view.index, name='index'), ]后臺視圖
hello/view.py代碼配置如下:from django.http import HttpResponse def index(request): print(request.GET) return HttpResponse("year is {}, month is {}, day is {}.".format(year, month, day))后臺列印輸出的結果如下:
備注: 是一個QueryDict物件,<QueryDict: {'year': ['2020'], 'month': ['09'], 'day': ['02']}>從上面已經接收到用戶的資訊了,就可以獲取相應的引數了,hello/view后臺腳本更新如下:
from django.http import HttpResponse def index(request): #第一個引數是獲取QueryDict的year #第二引數是默認值,表示拿不到資料,用預設值 year = request.GET.get('year', '2030') month = request.GET.get('month', 'Sep') day = request.GET.get('day', '8') return HttpResponse("year is {}, month is {}, day is {}.".format(year, month, day))網頁請求帶引數回傳的結果如下:

網頁請求不帶引數回傳的結果如下:

-
GET請求,位置引數
不推薦使用,位置要一一對應入座網址匹配到路由
hello/url.py配置規則from django.urls import re_path from hello import view app_name = 'hello' urlpatterns = [ # 位置引數 # [0-9]表示數字0-9,{4}表示取4位數字 re_path('([0-9]{4})/([0-9]{2})/([0-9]{2})/', view.index, name='index'), ]后臺視圖
hello/view.py腳本配置如下:def index(request, year, month, day): return HttpResponse("year is {}, month is {}, day is {}.".format(year, month, day))網頁輸入如下地址,請求回傳的結果如下:

-
GET請求,關鍵字引數
說明:
強烈推薦,優雅的方式.在瀏覽器輸入如下地址:
http://192.168.8.130:8888/2020/09/02路由視圖
hello/url.py配置規則from django.urls import re_path from hello import view app_name = 'hello' urlpatterns = [ # 關鍵字引數,(?<引數名>引數型別) re_path('(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})', view.index, name='index'), ]后臺視圖
hello/view.py腳本配置如下:from django.http import HttpResponse def index(request, **kwargs): # 輸出結果:{'year': '2020', 'month': '09', 'day': '02'} print(kwargs) year = kwargs.get('year') month = kwargs.get('month') day = kwargs.get('day') return HttpResponse("year is {}, month is {}, day is {}.".format(year, month, day))還可以換成另外一種寫法,更加靈活,但是用的也不是很多:
from django.http import HttpResponse # 不用考慮到函式引數的位置 def index(request, day, month, year): return HttpResponse("year is {}, month is {}, day is {}.".format(year, month, day))
2.2.4 POST請求
在devops/setting.py里把csrf關閉,不然會運行報錯:
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 默認開啟防止中間人CSRF攻擊,前期先注釋掉
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
網址匹配到路由hello/urls.py配置規則
from django.urls import path
from hello import view
app_name = 'hello'
urlpatterns = [
path('', view.index, name='index'),
]
后臺視圖hello/view.py腳本配置如下:
from django.http import HttpResponse, QueryDict
def index(request):
if request.method == "POST":
# POST方法
print(request.method)
# body是位元組編碼,b'year=2020&month=09&day=13'
print(request.body)
# 轉換為字典{'year': '2020', 'month': '09', 'day': '13'}
print(QueryDict(request.body).dict())
# <QueryDict: {'year': ['2020'], 'month': ['09'], 'day': ['13']}>
print(request.POST)
data = https://www.cnblogs.com/singvis/p/request.POST
year = data.get('year', '2030')
month = data.get('month', '9')
day = data.get('day', '8')
return HttpResponse("year is {}, month is {}, day is {}.".format(year, month, day))
模擬觸發POST流量:
[root@localhost ~]# curl -X POST http://192.168.8.130:8888/hello/ -d 'year=2020&month=09&day=13'
year is 2030, month is 9, day is 13.
看看我們后臺接收哪些資訊:

2.2.5 QueryDict介紹
在httprequest物件中,GET和POST屬性是django.http.QueryDict的實體,它是一個自定義的類似字典的類,用來處理同一個鍵帶多個值,無論使用GET,POST方式,他們最終都是通過QueryDict方法對傳入的引數進行處理,
3. MTV之模板
3.1 模板繼承
3.1.1 常規手段
-
創建模板
templates目錄及子目錄hello:mkdir -p devops/templates/hello備注:每一個APP對應一個目錄,
-
路由視圖
hello/urls.py配置規則from django.urls import path from hello import view app_name = 'hello' urlpatterns = [ path('list/', view.list, name='list'), ] -
后臺視圖
hello/view.py配置from django.shortcuts import render def list(request): users = [ {'username':'test01', 'age':18, 'hobby':'python'}, {'username':'test02', 'age':18, 'hobby':'java'}, {'username':'test01', 'age':18, 'hobby':'C'}, ] return render(request, 'hello/list.html', {'users':users})說明:本次練習,還沒涉及到資料庫,所以先本地創建資料,
-
新建模板
templates/hello/list.html配置<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>點滴技術</title> </head> <body> <p style="background-color: #77ee77">用戶串列</p> <table border="1"> <thead style="background-color: #00aced"> <tr> <td>username</td> <td>age</td> <td>hobby</td> </tr> </thead> <tbody> {% for user in users %} <tr> <td> {{ user.username }} </td> <td> {{ user.age }} </td> <td> {{ user.hobby }} </td> </tr> {% endfor %} </tbody> </table> <p style="background-color: yellow"> 著作權所有?點滴技術 </p> </body> </html> -
網頁輸入地址后,效果圖:

3.1.2 模板繼承
-
定義母板
在devops/templates目錄下新增一個base.html母板,<!doctype html> <html lang="en"> <head> <!-- 每個html的標簽變數,都可以自定義--> <title> {% block title %}NetDevOps{% endblock title %} </title> </head> <body> <!-- body變數,每個頁面都可以自定義內容--> {% block body %}這是body的內容{% endblock body %} <!-- 底部,每個html頁面固定樣式 --> <p style="background-color: yellow"> 著作權所有?點滴技術 </p> </body> </html> -
子頁面繼承
<!--繼承母版--> {% extends "base.html" %} <!--重寫title的內容--> {% block title %} 用戶的串列 {% endblock %} <!--重寫body的內容--> {% block body %} <table border="1"> <thead style="background-color: #00aced" > <tr> <td>username</td> <td>age</td> <td>hobby</td> </tr> </thead> <tbody> {% for user in users %} <tr> <td> {{ user.username }} </td> <td> {{ user.age }} </td> <td> {{ user.hobby }} </td> </tr> {% endfor %} </tbody> </table> {% endblock%}備注:公共部分代碼就不用寫出來了,減少了代碼冗余,
-
視圖
hello/view.py配置from django.shortcuts import render def userlist(request): users = [ {'username':'test01', 'age':18, 'hobby':'python'}, {'username':'test02', 'age':18, 'hobby':'java'}, {'username':'test03', 'age':18, 'hobby':'C'}, ] return render(request, 'hello/userlist.html', {'users':users}) -
效果圖:

4. Template模板過濾器
4.1 Django自帶常用過濾器
-
傳入引數的長度
{% if messages|length >= 3 %} The Messages is too long. {% else %} The messages is too short. {% endif %} -
default:預設值
{{ messages|default:"nothing" }}備注:如果傳入的值為false,則使用預設值,
-
first/last
{{ messages|first }} {{ messages|last }}備注:顯示串列第一個或最后一個元素,
-
join
說明:將串列轉為字串,{{ value|join:"-" }} -
length
說明:判斷長度,回傳布林值{{ messages|length}} {{ messages|length_is:"4"}} -
static
說明:加載本地圖片、css、js樣式等資源,通常使用CDN方式,# 方法1: {% load static %} <img src="https://www.cnblogs.com/singvis/p/{% static"images/favicon.png" %}" alt="Hi!" /> # 方法2: {% load static %} {% static "images/favicon.png" as myphoto %} <img src="https://www.cnblogs.com/singvis/p/{{ myphoto }}"></img> -
date
說明:時間格式化,回傳年-月-日 時-分-秒{{ messages|date:"Y/m/d" }}{{ messages|date:"H:i:s" }} -
safe
說明:預設情況下,django會對HTML等標簽進行自動轉義,如果要關閉自動轉義,可通過過濾器"|safe"的方式申明不用轉義,value = "https://www.cnblogs.com/singvis/p/ -
csrf_token
說明:用于跨站請求偽造保護<form action="" method='post'> {% csrf_token %} # 有了這個POST請求才能正常運行 <p> <input type="text" name="user"></p> <input type="submit"> </form> -
slice
說明:切片{{ messages|slice:":2"}}
4.2 自定義模板標簽和過濾器
-
定義標簽
創建目錄及檔案:hello/templatetags/mytag.pyfrom django import template register = template.Library() @register.filter def test(x, y): return int(x)*2 + int(y)qq -
模板視圖
<!--繼承母版--> {% extends "base.html" %} {% block title %}模板標簽{% endblock %} <!--重寫body的內容--> {% block body %} <!--自定義模板標簽--> {% load mytag %} <p> {{ "2"|test:"1" }}</p> {% endblock%}
5. 模型Model基礎
5.1 模型概念
簡單理解:模型對應資料庫中的表,模型中的一個類對應資料庫一張表;
5.1.1 常用欄位型別
-
字串:
CharFieLdfrom django.db import models class User(): username = models.CharField(max_length=20) -
整數:
IntegerFieldint_field = models.IntegerField() -
浮點數:
FloatFieldfloat_field = models.FloatField() -
自增欄位:
AutoFieldid_field = models.AutoField(primary_key=True) -
文本框:
TextFieldtext_field = models.TextField() -
郵箱:
EmailField
說明:用于檢查郵箱的合法性,mail_field = models.EmailField() -
日期:
DateField說明:
auto_now是被保存時,將時間設定為當前時間,通常表示last-modified,auto_now_add是首次被創建時,設定為當前時間,通常表示創建時間,date = models.DateField() -
檔案上傳:
Filefield
說明:upload_to必選引數,指檔案的上傳存放路徑,upload_file = models.FileField(upload_to='/usr/tmp/test')
5.1.2 常用欄位引數
- null
如果null=True將再資料庫存放一個空值NULL,預設為Flase,
該欄位是可以在資料中存放null值, - blank
如果blank=True,則允許該欄位為空白,預設是False,不允許為空,
該欄位是表單驗證是否允許為慷訓不為空的, - unique
如果unique=True,表示該欄位在整個表單中是唯一的,不重復的, - primary_key
如果primary_key=True, 表示該欄位在資料庫中是主鍵, - default = ''
用于定義預設值, - verbose_name
ForeignKey、ManyToManyField、和OneToOneField的備注資訊需要用到這個,
6. 建模及同步
6.1 設計一個簡單的模型
hello\models.py:
#!/usr/bin/env python3
#-*- coding:UTF-8 -*-
from django.db import models
class Devices(models.Model):
device_name = models.CharField(max_length=32, help_text='設備名稱')
ip = models.CharField(max_length=15, help_text='管理IP地址')
vendor = models.CharField(max_length=16, help_text='廠商')
device_type = models.CharField(max_length=6, help_text='設備型別')
model = models.CharField(max_length=32, help_text='設備型號')
sn = models.CharField(max_length=32, help_text='序列號')
os = models.CharField(max_length=16, help_text='作業系統')
version = models.CharField(max_length=32, help_text='版本')
def __str__(self):
return self.device_name
6.2 將模型同步到資料庫
-
生成遷移腳本
(py369) [root@localhost devops]# python manage.py makemigrations hello Migrations for 'hello': hello/migrations/0004_devices.py - Create model Devices -
展示遷移的sql陳述句
(py369) [root@localhost devops]# python manage.py sqlmigrate hello 0004 BEGIN; -- -- Create model Devices -- 此處省略... -
執行資料庫命令
(py369) [root@localhost devops]# python manage.py migrate hello Operations to perform: Apply all migrations: hello Running migrations: Applying hello.0004_devices... OK -
查看資料庫表

-
常用命令解釋
# 生產遷移腳本 python manage.py makemigrations <app_name> # 轉換后的sql陳述句 python manage.py sqlmigrate <app_name> <number> # 執行資料庫命令 python manage.py migrate # 所有APP及對應生效的migration python manage.py showmigrations # 將某個APP的migration重置 python manage.py migrate --fake hello # 強制執行某個版本的遷移腳本 python manage.py migrate --fake hello python manage.py migrate --fake hello 0004
7. ORM實作簡單的增刪改查
7.1 ORM概念
- ORM是對資料抽象建模并提供訪問介面的編程方式
- 模型中的一個類(class)表示一個表(table)
- 每一個屬性對應資料表中的一個欄位
- 呼叫資料表,就是實體化類的物件
7.2 增 | 刪 | 改 | 查
7.2.1 增加資料
(py369) [root@localhost devops]# python manage.py shell
In [1]: from hello.models import Devices
# 實體化物件
In [4]: D = Devices.objects.all()
In [5]: D
# 暫時還沒有資料,為空
Out[5]: <QuerySet []>
In [7]: data = https://www.cnblogs.com/singvis/p/{'device_name':'test-sw-01', 'ip':'192.168.1.1', 'vendor':'cisco','device_type':'switch','model':'c3850','sn':'001','os':'ios','version':'15.0'}
# 第一種創建方式(最常用)
In [8]: D.create(**data)
Out[8]: <Devices: test-sw-01>
# 第二種創建方式(防止重復,速度相對較慢):
# 回傳一個元組(物件,True或False)
In [10]: data2 = {'device_name':'test-sw-02', 'ip':'192.168.1.2', 'vendor':'cisco','device_type':'switch','model':'c3850','sn':'001','os':'ios','version':'15.0'}
In [14]: D.get_or_create(**data2)
Out[14]: (<Devices: test-sw-02>, True)
In [16]: D
Out[16]: <QuerySet [<Devices: test-sw-01>, <Devices: test-sw-02>]>
7.2.2 洗掉洗掉
資料庫表中的資料(偷偷增加了一臺設備):

In [1]: from hello.models import Devices
# 洗掉一條記錄
# 第一種方法:get
In [4]: D = Devices.objects.get(device_name = 'test-sw-02')
In [5]: D.delete()
Out[5]: (1, {'hello.Devices': 1})
# 第二種方法:filter
In [2]: Devices.objects.filter(device_name='test-sw-03').delete()
Out[2]: (1, {'hello.Devices': 1})
# 先還原資料,再洗掉所有的記錄
In [5]: Devices.objects.all().delete()
Out[5]: (3, {'hello.Devices': 3})
7.2.3 修改資料
# 第一種方法:
In [2]: D = Devices.objects.get(device_name='test-sw-03')
In [3]: D.device_name = 'test-sw-13'
In [4]: D.save()
In [5]: Devices.objects.all()
Out[5]: <QuerySet [<Devices: test-sw-01>, <Devices: test-sw-02>, <Devices: test-sw-13>]>
# 第二種方法:
# 指定欄位更新,偷偷去看下后臺的ID是多少
In [6]: Devices.objects.filter(id=11)
Out[6]: <QuerySet [<Devices: test-sw-13>]>
In [7]: Devices.objects.filter(id=11).update(device_name='test-sw-03')
Out[7]: 1
In [8]: Devices.objects.get(device_name='test-sw-03')
Out[8]: <Devices: test-sw-03>
# 多個欄位更新
In [26]: data = https://www.cnblogs.com/singvis/p/{'vendor':'huawei','device_type':'switch','model':'S9303','sn':'001','os':'VRP'}
In [27]: Devices.objects.filter(id=11).update(**data)
Out[27]: 1
最終效果如下(通過資料庫查詢):

7.2.4 查看資料
-
查詢多條資料
串列嵌套一個字典(QuerySet物件)
# 查詢所有 In [30]: D = Devices.objects.all() In [31]: D Out[31]: <QuerySet [<Devices: test-sw-01>, <Devices: test-sw-02>, <Devices: test-sw-03>]> # 每個物件及物件的屬性 In [32]: D[0] Out[32]: <Devices: test-sw-01> In [33]: D[0].device_name Out[33]: 'test-sw-01' # 切片,不支持負索引 In [34]: D[:2] Out[34]: <QuerySet [<Devices: test-sw-01>, <Devices: test-sw-02>]> # 遍歷 In [36]: for d in D: ...: print(d.device_name) ...: test-sw-01 test-sw-02 test-sw-03 # 回傳指定的欄位(values_list 和 values) In [37]: D.values_list('device_name','ip') Out[37]: <QuerySet [('test-sw-01', '192.168.1.1'), ('test-sw-02', '192.168.1.2'), ('test-sw-03', '192.168.1.3')]> In [39]: D.values('device_name','vendor') Out[39]: <QuerySet [{'device_name': 'test-sw-01', 'vendor': 'cisco'}, {'device_name': 'test-sw-02', 'vendor': 'cisco'}, {'device_name': 'test-sw-03', 'vendor': 'huawei'}]> -
查詢一條資料
# 第一種方法: In [2]: D = Devices.objects.get(device_name='test-sw-01') In [3]: D # 回傳的是一個物件 Out[3]: <Devices: test-sw-01> # 取物件的屬性值 In [4]: D.device_name Out[4]: 'test-sw-01' In [5]: D.vendor Out[5]: 'cisco # 第二種方法: In [6]: data = https://www.cnblogs.com/singvis/p/{'device_name':'test-sw-01'} In [7]: D = Devices.objects.get(**data) In [8]: D.device_name Out[8]: 'test-sw-01'- 過濾查詢
In [9]: Devices.objects.filter(device_name='test-sw-01') Out[9]: <QuerySet [<Devices: test-sw-01>]> In [11]: Devices.objects.filter(**data) Out[11]: <QuerySet [<Devices: test-sw-01>]>- 過濾常用方法:
# 不區分大小寫:<屬性值>__iexact In [16]: Devices.objects.filter(device_name__iexact='test-sw-01') Out[16]: <QuerySet [<Devices: test-sw-01>]> # 包含匹配:<屬性值>__contains In [17]: Devices.objects.filter(device_name__contains='sw') Out[17]: <QuerySet [<Devices: test-sw-01>, <Devices: test-sw-02>, <Devices: test-sw-03>]> # 模糊匹配,不磁區大小寫:<屬性值>__icontains In [18]: Devices.objects.filter(device_name__icontains='sw') Out[18]: <QuerySet [<Devices: test-sw-01>, <Devices: test-sw-02>, <Devices: test-sw-03>]> # 正則模糊匹配:<屬性值>__regex In [20]: Devices.objects.filter(device_name__regex='-03$') Out[20]: <QuerySet [<Devices: test-sw-03>]> # 正則模糊匹配,不區分大小寫:<屬性值>__regex In [21]: Devices.objects.filter(device_name__iregex='^test') Out[21]: <QuerySet [<Devices: test-sw-01>, <Devices: test-sw-02>, <Devices: test-sw-03>]> # 排除過濾:<屬性值>__contains In [22]: Devices.objects.exclude(device_name__contains='test-sw-01') Out[22]: <QuerySet [<Devices: test-sw-02>, <Devices: test-sw-03>]> # 包含帶有sw的device_name,但排除了vendor是cisco廠商的 In [23]: Devices.objects.filter(device_name__contains='sw').exclude(vendor='cisco') Out[23]: <QuerySet [<Devices: test-sw-03>]> # filter其他常用過濾查詢方法 __exact:精確匹配 __iexact:精確匹配,忽略大小寫 __gt:大于 __gte:大于等于 __lt:小于 __lte:小于等于 __in:在一個list串列范圍內 __startswith:以...開頭 __startswith:以...開頭,忽略大小寫 __endswith:以...結尾 __range:在...范圍內 __year:日期的年份 __month:日期的月份 __day:日期的日數 __isnull=True/False:欄位是否為空get和filter的區別:# 都可以獲取到指定的物件; # get是獲取唯一資料的場景,資料不存在會報錯; # filter適用于任何場景,回傳是一個QuerySet物件,資料不存在則回傳是空的物件,-
排序查詢
# 正序 In [32]: Devices.objects.all().order_by('device_name') Out[32]: <QuerySet [<Devices: test-sw-01>, <Devices: test-sw-02>, <Devices: test-sw-03>]> # 倒序,前面加 In [33]: Devices.objects.all().order_by('-device_name') Out[33]: <QuerySet [<Devices: test-sw-03>, <Devices: test-sw-02>, <Devices: test-sw-01>]>
8. 打通MTV
8.1 創建模型
參見以上的hello/models.py的配置,
8.2 創建視圖view
from django.shortcuts import render
from hello.models import Devices
def devicelist(request):
# 物件實體化
devices = Devices.objects.all()
# {'devices':devices}表示傳參
return render(request, 'hello/device.html', {'devices':devices})
8.3 創建模板
<!--繼承母版-->
{% extends "base.html" %}
<!--重寫title的內容-->
{% block title %}設備串列{% endblock %}
<!--重寫body的內容-->
{% block body %}
<p style="background-color: #77ee77">設備串列</p>
<!--表格-->
<table border="1">
<!-- 表頭-->
<thead style="background-color: #00aced" >
<tr>
<td>設備名稱</td>
<td>IP地址</td>
<td>廠商</td>
<td>設備型別</td>
<td>型號</td>
<td>序列號</td>
<td>作業系統</td>
<td>版本號</td>
</tr>
</thead>
<!--表的正文-->
<tbody>
{% for device in devices %}
<tr>
<td> {{ device.device_name }} </td>
<td> {{ device.ip }} </td>
<td> {{ device.vendor }} </td>
<td> {{ device.device_type }} </td>
<td> {{ device.model }} </td>
<td> {{ device.sn }} </td>
<td> {{ device.os }} </td>
<td> {{ device.version }} </td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock%}
8.4 創建路由視圖URL
from django.urls import path
from hello import view
app_name = 'hello'
urlpatterns = [
path('devicelist', view.devicelist, name='devicelist'),
]
8.5 效果圖如下:

大家先不要在意前端效果,后面的專案,再把UI這塊優化好,先到這里了,大家學會了嗎?
好不容易碼完這篇了,大家點個贊吧!
如果喜歡的我的文章,歡迎關注我的公眾號:點滴技術,掃碼關注,不定期分享

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/201728.html
標籤:Python
上一篇:pytorch 中 torch.no_grad()、requires_grad、eval()
下一篇:FLOYD和DIJ記錄Path
