Django ORM
Python微信訂餐小程序課程視頻
https://edu.csdn.net/course/detail/36074
Python實戰量化交易理財系統
https://edu.csdn.net/course/detail/35475
目錄* Django ORM
+ ORM實操之數據庫遷移
+ ORM實操之字段的修改
+ ORM實操之數據的增刪改查
+ 數據庫同步
+ ORM創建表關系
- Django請求生命周期流程圖
- 路由匹配
- 無名分組
- 有名分組
- 反向解析
- 無名分組和有名分組反向解析
Django ORM
ORM:對象映射關系程序
通過orm將編程語言的對象模型和數據庫的關系模型建立映射關系,這樣我們在使用編程語言對數據庫進行操作的時候可以直接使用編程語言的對象模型進行操作就可以了,而不用直接使用sql語言;
python與MySQL映射關系
| 類 | -------> | 表 |
| 對象 | -------> | 表里面的數據 |
| 對象點屬性 | -------> | 字段對應的值 |
ORM實操之數據庫遷移
?我們的模型類需要寫在應用下的models.py文件中
# SQL原生語句和ROM創建的區別class User(models.Model):# id int primary key auto\_incrementid = models.AutoField(primary_key=True)# name varchar(32)name = models.CharField(max_length=32) # CharField必須要加max\_length參數# age intage = models.IntegerField()???數據庫遷移命令(重點)
- 只要修改了models.py文件執行了和數據庫相關的命令,就重新執行下面這兩條命令:python3 manage.py makemigrations、python3 manage.py migrate
- 或者打開Tools,點擊RUN manage.py Task,輸入makemigrations
??不指定id字段和主鍵等,ORM會自動創建id
# 如果你不指定主鍵 那么orm會自動幫你創建一個名為id的主鍵字段 class user(models.Model):username = models.CharField(max_length=32)# 就不用寫id了···,需要定制id,就寫上~ORM實操之字段的修改
# 原來的表 class user(models.Model):username = models.CharField(max_length=32)# 增加字段(兩種方法)password = models.IntegerField('密碼',null=True) # 該字段可以為空is_delete = models.IntegerField(default=0) # 默認值# 修改字段 直接改代碼,然后執行makemigrations,數據庫遷移 # 刪除 直接刪除或者注釋掉代碼,然后執行makemigrations,數據庫遷移ORM實操之數據的增刪改查
查詢操作
username = request.POST.get('username') # 獲取用戶post從頁面提交的數據,username是獲取到用戶提交的數據# 1.查詢數據 # select * from user where name=username; user_obj_list = models.User.objects.filter(name=username) # 獲取到的是列表,看成列表套數據對象 obj_info = user_obj_list[0] # 獲取id、name、age print(obj_info.id, obj_info.name, obj_info.age) # 1 hammer 18 # 或這下面這樣提取列表數據也可以 user_obj = models.User.objects.filter(name=username).first() '''如果用戶提交的信息不存在返回None'''# 登錄功能示例 user_check = models.User.objects.filter(name=username,password=password).first() # 等價于select * from user where name=username and pwd = password if user_check:return HttpResponse('登錄成功') # 2.添加數據 # insert into user(name,pwd) values(username,password); models.User.objects.create(name=username,pwd=password)# 3.查詢所有的數據,展示所有數據到前端頁面,通過for循環在html頁面獲取表數據 # select * from user; models.User.objects.all() # 返回列表[obj1,obj2,obj3,obj4]# 4.修改數據 models.User.objects.filter(id=edit_id).update(name=username,pwd=password) # 或者 edit_obj.name = username edit_obj.pwd = password edit_obj.save()# 5.刪除數據 models.User.objects.filter(id=delete_id).delete()數據庫同步
python manage.py makemigrations
2. inspectdb 表名語句反向操作數據庫,反向輸出sql語句對應的類
ps:如果inspectdb后不跟表名,那么就會將該數據庫內的所有表反向解析成類(python語句)
# 數據庫里面已經有一些表,我們如何通過django orm操作? 1.照著數據庫表字段自己在models.py 2.django提供的反向同步操作: 1.先執行數據庫遷移命令 完成鏈接python manage.py makemigrations 2.查看代碼python manage.py inspectdbclass Userinfo(models.Model):id = models.IntegerField(blank=True, null=True)name = models.CharField(max_length=32, blank=True, null=True)pwd = models.IntegerField(blank=True, null=True)class Meta:managed = Falsedb_table = 'userinfo'ORM創建表關系
表與表之間的關系有一下三種:
一對多、多對多、一對一,沒關系暫且排外,下面演示如何通過ORM來創建外鍵確立表關系~
ORM創建外鍵字段的位置:
- 一對多:創建在多的一方
- 一堆一:創建在任何一方都可以,但是推薦創建在查詢頻率較高的表中
- 多對多(兩種方式):
- 自己創建第三張表
- 創建在任何一方都可以,但是推薦創建在查詢頻率較高
注意:
- 外鍵不需要寫id,會自動添加id,比如author_id,不需要寫_id,orm自動補充
- ORM自動創建書籍和作者的第三張表,只有多對多關系表被單獨創建出來
- 外鍵被當作虛擬字段,創建表完成后,不會實例化出來,而是告訴了ORM創建第三張表的關系
- Django2.0版本以上,在創建外鍵和一對一關系的時候,需要添加級聯更新參數on_delete=models.CASCADE,不然會報錯,只有OneToOneField和ForeignKey需要寫,ManyToManyField不需要
Django請求生命周期流程圖
路由匹配
- 路由:通俗理解為除去ip和port之后的地址
👉path官網文檔
👉URL調度
👉“江狗”
在新版本***Django2.x***中,url的路由表示用path和re_path代替;
模塊的導入由django1.x版本的from django.conf.urls import url,include變成現在的Django2.x中的from django.urls import path, re_path, include
Django提供了兩種設計URL的方法: path和re_path,它們均支持向視圖函數或類傳遞參數。path是正常參數傳遞,re_path是采用正則表達式regex匹配;
- path方法:采用雙尖括號<變量類型:變量名>或<變量名>傳遞,例如, 或。
- re_path方法: 采用命名組(?P<變量名>表達式)的方式傳遞參數。
- path支持匹配的數據類型只有str,int, slug, uuid四種。一般來說re_path更強大,但寫起來更復雜一些
簡單示例
'''urls.py''' from django.contrib import admin from django.urls import path,re_path,include from app01 import viewsurlpatterns = [# 路由匹配re_path(r'test',views.test),re_path(r'testadd',views.testadd) ]'''views.py''' from django.shortcuts import render,HttpResponse,redirect # Create your views here. def test(request):return HttpResponse('from test') def testadd(request):return HttpResponse('from testadd')''' 這樣匹配的話,相當于使用正則表達式,如果url后面寫test返回fromtest,那么再寫testadd呢?也會返回from test,這是一種包含關系,需要更明確的去區別,比如寫test/,或者testadd/,建議在末尾加上/ '''urlpatterns = [path('admin/', admin.site.urls),# 限制開頭re_path(r'^test/',views.test),# 限制開頭和結尾re_path(r'^testadd/$',views.testadd) ]- Django特性:如果在url后面寫路徑沒有寫/,那么會自動補充/,相當于跳轉頁面,如果不想使用該特性,可以在setting.py文件中取消:APPEND_SLASH = False
下例中,我們分別以path和re_path 定以了兩個urls,它們是等效的,把文章的id(整數類型)傳遞給了視圖。re_path里引號前面的小寫r表示引號里為正則表達式, ^代表開頭,$代表以結尾,\d+代表正整數
# blog/urls.py from django.urls import path, re_path from . import viewsurlpatterns = [path('blog/articles//', views.article_detail, name = 'article\_detail'),re_path(r'^blog/articles/(?P\d+)/$', views.article_detail, name='article\_detail'), ]# blog/views.py def article\_detail(request, id):# 展示某篇文章在使用path和re_path方法設計urls需注意:
- url中的參數名要用尖括號,而不是圓括號;
- 匹配模式的最開頭不需要添加斜杠/,但建議以斜杠結尾;
- 使用re_path時不一定總是以$結尾,有時不能加。比如下例中把blog.urls通過re_path加入到項目urls中時就不能以$結尾,因為這里的blog/并不是完整的url,只是一個開頭而已。
無名分組
涉及到urls.py寫對應關系,無名分組后如果不給視圖函數傳參,那么就會報錯
通俗理解:路由使用正則,正則匹配加括號分組,當作了視圖函數的第二個位置參數
'''urls.py'''from django.contrib import admin from django.urls import path,re_path,include from app01 import viewsurlpatterns = [path('admin/', admin.site.urls),# 匹配數字# re\_path(r'^test/[0-9]{4}/$',views.test),# 無名分組,匹配1個到多個正整數re_path(r'^test/(\d+)/$',views.test), ]'''views.py''' def test(request,num):print(num) # 1234return HttpResponse('from test')'''路由使用正則,正則匹配加括號分組,當作了視圖函數的第二個位置參數'''有名分組
在使用路由的時候,正則表達式可以起別名,別名當作關鍵字參數傳給視圖函數;
沒有按關鍵字參數寫報錯
按別名,傳參
'''urls.py''' urlpatterns = [ re_path(r'^test/(?P\d+)/$',views.test), ] '''views.py''' def test(request,id):print(id)return HttpResponse('from test')# 有名分組,將匹配到的數字命名成id,當成關鍵字參數傳給視圖函數注意:
- 無名分組和有名分組不能混合使用
- 相同分組可以混合使用
反向解析
反向解析解決了當路由頻繁變化的時候,html界面上的連接地址實現動態解析;
'''urls.py''' # 1、給路由與視圖函數對應關系添加一個別名 from django.contrib import admin from django.urls import path,re_path,include from app01 import viewsurlpatterns = [path('admin/', admin.site.urls),# 反向解析path('index/',views.index,name='index\_name'),path('home/',views.home) ]'''views.py''' from django.shortcuts import HttpResponse,render,reversedef index(request):return HttpResponse('from index')def home(request):print(reverse('index\_name'))# 或者# return redirect('index\_name')return render(request,'home.html')'''home.html''' <a href="{% url 'index\_name' %}">111</a> <a href="{% url 'index\_name' %}">111</a> <a href="{% url 'index\_name' %}">111</a>總結:
當路由頻繁變化的時候,html界面上的連接地址如何做到動態解析 # 1.給路由與視圖函數對應關系添加一個別名(名字自己指定 只要不沖突即可)url(r'^index/',views.index,name='index\_name') # 2.根據該別名動態解析出一個結果,該結果可以直接訪問到對應的路由前端<a href="{% url 'index\_name' %}">111</a>后端from django.shortcuts import reversereverse('index\_name')ps:redirect括號內也可以直接寫別名無名分組和有名分組反向解析
如果有分組的情況,不寫數字參數會報錯
'''路由''' urlpatterns = [path('admin/', admin.site.urls),# 反向解析re_path(r'index/(\d+)/',views.index,name='index\_name'),path('home/',views.home) ] '''后端''' def index(request):return HttpResponse('from index') def home(request):print(reverse('index\_name'))return render(request,'home.html') '''前端''' <a href="{% url 'index\_name' %}">111</a>無名分組反向解析
# 無名分組 1、起別名 url(r'^index/(\d+)/',views.index,name='index\_name') 2、前端 <a href="{% url 'index\_name' 1 %}"></a> # 只要給個數字即可 3、后端 reverse('index\_name',args=(1,)) # 只要給個數字即可有名分組反向解析
# 無名分組 1、起別名 url(r'^index/(?P\d+)/',views.index,name='index\_name') 2、前端 <a href="{% url 'index\_name' id=1 %}"></a> # 只要給個數字即可 3、后端 reverse('index\_name',kwargs={'id':1}) # 只要給個數字即可總結:
- 再次驗證了,分組對應傳的參數,無名對應位置參數,有名對應關鍵字參數
- 分組了,一定要記得傳參數,無名分組傳位置參數,有名分組傳關鍵字參數
- 需要注意的是django2.0版本的變化,path和re_path寫路由,django1.0版本用到的是url寫路由,在前端頁面寫反向解析的時候用到的是url和Django1.0一樣,一定要區別開來
- 上面用參數用數字代替,在實際應用中經常使用數據主鍵值(視圖函數的參數)
👉參考文獻:大江狗
總結
以上是生活随笔為你收集整理的Django ORM的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【预测模型】基于麻雀算法改进ELMAN神
- 下一篇: svn强制要求提交注释