本章開始我們正式進入到實戰專案開發程序,如何從需求分析獲得的物體資料轉到模型設計中來,變成Django專案中得模型層,當然,第一步還是在VS2019 IDE環境重創建一個工程專案,本文我們把工程名稱命名為IndDemo,如下圖:

VS2019創建的Django專案結構如下圖

現在按F5除錯程式,又來到Django熟悉的歡迎頁面了,

接下來讓開始這趟實戰之旅吧!
1.1. 物體關系圖
從上一章需求涉及到的物體,來構建我們的物體關系圖吧,這里的步驟也相當于早期開發設計的表結構設計,只是如前面章節說的有了ORM機制后,我們討論采用物件模型來設計和討論物體可能更適合于實際的場景討論,便于團隊在同一個頻道下溝通,當然這里實質上與表設計沒有太多本質的區別,但是多對多等中間表在物體關系圖中就看不到了,表結構設計時就不能忽略這個中間表的存在,產品經理更專注于需求而不是資料庫存盤結構是不是更符合專業分工?開發人員也不用大費周章來折騰表結構的優化了,嗯,這些可以丟給DBA來優化吧,

本圖采用網址ponyorm網站在線繪制,網址:https://editor.ponyorm.com/.
1.2. Django model層
為了便于對照學習和理解,我們新增一個新的APP 命名為:Task來專門處理這個業務,不修改默認的APP里的代碼,也便于程序中可以通過這個默認APP功能,參照它的結構和語法等,

現在我們的工程目錄結構如下:

打開Task.models.py檔案撰寫我們物體關系圖的模型代碼吧,作者本人比較習慣“大駝峰”命名法也就是首字母都大寫的模式TaskNum,后面很多命名都會采用這個方式,不采用python主流的蛇形命名法的task_num方式,純屬個人習慣,我們依據設計我們開始構建我們的model代碼如下:
from django.db import models from django.contrib.auth.models import User PRIORITY=((1,u'正常'),(2,u'急'),(3,u'緊急')) class Task(models.Model): TASK_STATE=((1,u'未處理'),(4,u'處理成功'),(5,u'執行中'),(99,u'完成'),(-1,u'已取消')) TaskId = models.AutoField(primary_key=True, db_column='task_id') TaskNum = models.IntegerField(u'任務號', null=False, db_column='task_num') Source = models.CharField(u'源地址', null=False, max_length=50, db_column='source') Target = models.CharField(u'目標地址', null=False, max_length=50, db_column='target') Barcode = models.CharField(u'容器條碼', null=False, max_length=50, db_column='barcode') State = models.IntegerField(u'狀態', choices=TASK_STATE, null=False, db_column='state') Priority = models.IntegerField(u'優先級', choices=PRIORITY, null=True, db_column='priority') BeginDate = models.DateTimeField(u'開始時間',null=True, db_column='begin_date') EndDate = models.DateTimeField(u'結束時間',null=True, db_column='end_date') SystemDate = models.DateTimeField(u'系統時間', null=False, auto_now_add=True, db_column='system_date') User = models.ForeignKey(User, verbose_name="操作員", on_delete=models.CASCADE,db_column='user_id') class Meta: db_table = 'task_task' ordering = ['-Priority','TaskId'] verbose_name = verbose_name_plural = "任務" def __str__(self): return str(self.TaskNum) class Job(models.Model): JOB_STATE=((1,u'新作業'),(2,u'下達執行'), (99,u'完成'),(-1,u'已取消')) JobId = models.AutoField(primary_key=True, db_column='job_id') Task = models.ForeignKey('Task', verbose_name="任務", blank=True, on_delete=models.CASCADE) TaskNum = models.IntegerField(u'任務號', null=False, db_column='task_num') OrderNo = models.IntegerField(u'順序號', null=False, db_column='order_no') Source = models.CharField(u'源地址', null=True, max_length=50, db_column='source') Target = models.CharField(u'目標地址', null=True, max_length=50, db_column='target') Executor = models.CharField(u'執行器', null=False,blank=True, max_length=50, db_column='executor') State = models.IntegerField(u'狀態', choices=JOB_STATE, null=False, db_column='state') Priority = models.IntegerField(u'優先級', choices=PRIORITY, null=True, db_column='priority') BeginDate = models.DateTimeField(u'開始時間',null=True, db_column='begin_date') EndDate = models.DateTimeField(u'結束時間',null=True, db_column='end_date') SystemDate = models.DateTimeField(u'系統時間', null=False, auto_now_add=True, db_column='system_date') Barcode = models.CharField(u'條碼', null=False, max_length=50, db_column='barcode') User = models.ForeignKey(User, verbose_name="操作員", on_delete=models.CASCADE,db_column='user_id') class Meta: db_table = 'task_job' ordering = ['JobId'] verbose_name = verbose_name_plural = "作業" def __str__(self): return str(self.TaskNum) +'-'+str(self.OrderNo)
1.3. make migrations創建資料庫遷移
首先,我們在專案的settings.py檔案里登記我們新增加的APP,代碼如下:
INSTALLED_APPS = [ 'app', 'Task', # Add your apps here to enable them 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ]
然后,在IDE通過選單就可以創建新建model產生的資料庫遷移,如下圖:


1.4. migrate 遷移資料庫
同樣在IDE視窗可以直接執行遷移命令,執行完資料遷移命令,工程默認鏈接的SQLite資料庫就包含這次我們創建的資料表了,

通過資料庫工具查看資料檔案里面的表創建情況,

1.5. Create Superuser
由于我們的model Task中定義了User這個參考django.contrib.auth.models.User的外鍵非空屬性,我們需要創建一個Django Admin的超級用戶,才能正常的保存Task 模型,

按照命令提示創建好超級用戶我們就可以通過ORM操作資料庫了,
1.6. Django ORM操作
Django ORM提供了諸多的API介面,詳情請參考官網檔案或網上教程,筆者的專案實戰也是遇到某類問題了,也是大量通過搜索引擎來找到相關的使用方法來改進功能代碼的, 實戰專案使用到ORM的操作很多,未來我們會逐步的使用到時,會進一步說明,本章節只舉一些常用的例子,
通過ORM我們可以不關心資料庫表結構,采用ORM機制就可以CRUD表里的資料了,資料將按照物件的方式的方式回傳,

1.回傳所有的Task物件
>>> from Task.models import Task >>> Task.objects.all() <QuerySet []>
2.新增Task物件
>>> a=Task(None,'1001','121','1-1-1001','2002001',1,1,None,None,None,1) >>> a.save() >>> Task.objects.all() <QuerySet [<Task: 1001>]>
通過資料庫工具也能看到這條新創建的Task

3.通過TaskId獲取Task物件
>>> Task.objects.filter(pk=1)
<QuerySet [<Task: 1001>]>
>>> Task.objects.get(TaskId=1)
<Task: 1001>
注意上面get方法的兩個不同的屬性
4.通過dict物件創建Task物件,這個模式后面用在以Json格式從前臺提交資料會非常方便
>>>data=https://www.cnblogs.com/haozi0804/p/{"TaskNum":"1002","Source":"122","Target":"1-1-1002","Barcode":"2002002","State":1,"Priority":1,"User_id":1}
>>> model=Task(**data)
>>> model.save()
>>> Task.objects.all()
<QuerySet [<Task: 1001>, <Task: 1002>]>
注意:User外鍵物件必須通過_id賦值"User_id":1,通常在變數前加一個星號(*)表示這個變數是元組/串列,加兩個星號表示這個引數是字典,
5.匹配條件
>>> Task.objects.filter(TaskNum='1001') <QuerySet [<Task: 1001>]>
6.不匹配條件
>>> Task.objects.exclude(TaskNum='1001') <QuerySet [<Task: 1002>]>
7.獲取單條資料(主鍵唯一)
>>> Task.objects.get(pk=1) <Task: 1001> >>> Task.objects.get(TaskId=1) <Task: 1001>
8.大于 __gt
>>> Task.objects.filter(pk__gt=1)
<QuerySet [<Task: 1002>]>
9.大于等于 __gte
>>> Task.objects.filter(pk__gte=1)
<QuerySet [<Task: 1001>, <Task: 1002>]>
10.小于 __lt
>>> Task.objects.filter(pk__lt=2)
<QuerySet [<Task: 1001>]>
11.小于等于 __lte
>>> Task.objects.filter(pk__lte=2)
<QuerySet [<Task: 1001>, <Task: 1002>]>
12.大于和小于, 1 < TaskId < 5
>>> Task.objects.filter(pk__gt=1,pk__lt=5)
<QuerySet [<Task: 1002>]>
13.包含 __in []
>>> Task.objects.filter(pk__in=[1,2,3,4,5])
<QuerySet [<Task: 1001>, <Task: 1002>]>
14.不包含,not in
>>> Task.objects.exclude(pk__in=[2,3,4,5])
<QuerySet [<Task: 1001>]>
15.為空:isnull=True
>>> Task.objects.filter(BeginDate__isnull=True)
<QuerySet [<Task: 1001>, <Task: 1002>]>
16.匹配,大小寫敏感 __contains
>>> Task.objects.filter(Barcode__contains="2001") <QuerySet [<Task: 1001>]>
17.匹配,大小寫不敏感 __icontains
>>> Task.objects.filter(Barcode__icontains="2001") <QuerySet [<Task: 1001>]>
18.范圍,__range
>>> Task.objects.filter(pk__range=[2,6])
<QuerySet [<Task: 1002>]>
19.排序,order by
>>> Task.objects.all().order_by('pk') <QuerySet [<Task: 1001>, <Task: 1002>]>
20.倒排序,order by
>>> Task.objects.all().order_by('-pk') <QuerySet [<Task: 1002>, <Task: 1001>]>
更多的ORM查詢操作查閱官網檔案,上面是業務編程程序用得比較多的一些過濾查詢方法,
1.7. 小節
本章我們著重在通過構建物體和物體關系圖,物體的屬性通常來自業務需求分析和設計時增加的一些必要的欄位,如:時間戳、創建物件的用戶等就是為了便于查找、定位、過濾資料,以及業務管理上考慮必要增加的一些多出來的物體屬性,這里筆者由于歷史習慣,表欄位命名又采用蛇形命名法,所以增加了一個強制欄位名稱的屬性db_column='user_id'都是個人習慣緣故,如果全部采用蛇形命名法這個屬性就可以去掉了,完成了model的構建后,我們就可以進行展開業務邏輯的開發了,
下一章我們講講Django后臺開發的利器 Django Admin,來快速的構建一個后臺管理框架,你會發現Django給我們省了好多好多事情,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/75666.html
標籤:Python
