Django模型層之單表操作
阿新 • • 發佈:2018-11-24
MVC或者MVC框架中包括一個重要的部分,就是ORM,它實現了資料模型與資料庫的解耦,即資料模型的設計不需要依賴於特定的資料庫,通過簡單的配置就可以輕鬆更換資料庫。ORM是“物件-關係-對映”的簡稱。
sql中的表
# 建立表 create TABLE employee( id INT PRIMARY KEY auto_increment, name varchar(20), gender BIT default 1, birthday DATA, departmentVARCHAR(20), salary DECIMAL(8,2) unsigned,) ); # 新增一條表記錄: INSERT employee(name, gender, birthday, salary, department) VALUES ('alex', '1', '1985-12-12', 8000, '保潔部'); # 查詢一條表記錄: SELECT * FROM employee WHERE age=24; # 更新一條表記錄: UPDATE employee SETbirthday='1989-10-24' WHERE id=1; # 刪除一條表記錄: DELETE FROM employee WHERE name='alex'
而對應的Python的類物件
class Employee(models.Model): id=models.AutoField(primary_key=True) name=models.CharField(max_length=32) gender=models.BooleanField() birthday=models.DateField() department=models.CharField(max_length=32) salary=models.DecimalField(max_digits=8,decimal_places=2) #新增一條表記錄: emp=Employee(name='alex', gender=True, birthday='1985-12-12',epartment='保潔部') emp.save() # 查詢一條表記錄 Employee.objects.filter(age=24) # 更新一條表記錄 Emplyoee.objects.filter(id=1).update(birthday='1989-10-24') # 刪除一條表記錄 Emplypee.objects.filter(name='alex').delete()
1.生成表模型
在該應用的models.py中建立模型:
from django.db import models # Create your models here. class Book(models.Model): id = models.AutoField(primary_key=True) title = models.CharField(max_length=32, unique=True) pub_date = models.DateField() price = models.DecimalField(max_digits=8, decimal_places=2) # max number = 999999.99 publish = models.CharField(max_length=32)
將模型轉為mysql資料庫中的表,需要在settings中配置:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME':'bms', # 要連線的資料庫,連線前需要建立好 'USER':'root', # 連線資料庫的使用者名稱 'PASSWORD':'', # 連線資料庫的密碼 'HOST':'127.0.0.1', # 連線主機,預設本級 'PORT':3306 # 埠 預設3306 } }
然後我們需要找到總專案包下的__init__.py檔案,寫入
import pymysql pymysql.install_as_MySQLdb()
最後通過兩條資料庫遷移命令即可在指定的資料庫中建立表 :
>>> python manage.py makemigrations
>>> python manage.py migrate
注意:
確保配置檔案中的INSTALLED_APPS中寫入我們建立的app名稱
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', "book" ] # book是應用名
如果你的Django版本是1.0而且Python版本高於3.4,可能會報錯如下:
django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.3 or newer is required; you have 0.7.11.None
需要修改:
通過查詢路徑C:\Programs\Python\Python36-32\Lib\site-packages\Django-2.0-py3.6.egg\django\db\backends\mysql\base.py 這個路徑裡的檔案把下面兩行程式碼註釋掉就ok了。(這個路徑並不是固定的,只要找到Python\django裡的mysql檔案)
if version < (1, 3, 3): raise ImproperlyConfigured("mysqlclient 1.3.3 or newer is required; you have %s" % Database.__version__)
如果你還想要在螢幕上列印轉換過程中的sql,需要在settings中進行如下配置:
LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'console':{ 'level':'DEBUG', 'class':'logging.StreamHandler', }, }, 'loggers': { 'django.db.backends': { 'handlers': ['console'], 'propagate': True, 'level':'DEBUG', }, } }
2.增刪改查
新增表記錄
方法1:
# create方法的返回值book_obj就是插入book表中的python葵花寶典這本書籍紀錄物件 book_obj=Book.objects.create(title="python葵花寶典",state=True,price=100,publish="蘋果出版社",pub_date="2012-12-12")
方法2:
book_obj=Book(title="python葵花寶典",state=True,price=100,publish="蘋果出版社",pub_date="2012-12-12") book_obj.save()
例:views.py
from django.shortcuts import render,HttpResponse # Create your views here. from app01.models import Book def index(request): book_obj = Book.objects.create(title="Python葵花寶典", state=True, pub_date="2012-12-12", price=100, publish='人民出版社') book_obj.save() book_obj_2 = Book(title="Python一陽指", state=True, pub_date='2012-12-12', price=100, publish='人民出版社') book_obj_2.save() return HttpResponse("OK!")
urls.py
from django.contrib import admin from django.urls import path from app01 import views urlpatterns = [ path('admin/', admin.site.urls), path('index/', views.index), ]
用瀏覽器登入首頁後,再查詢結果:
+----+--------------------+-------+------------+--------+-----------------+ | id | title | state | pub_date | price | publish | +----+--------------------+-------+------------+--------+-----------------+ | 1 | Python葵花寶典 | 1 | 2012-12-12 | 100.00 | 人民出版社 | | 2 | Python一陽指 | 1 | 2012-12-12 | 100.00 | 人民出版社 | +----+--------------------+-------+------------+--------+-----------------+
查詢表記錄
查詢API
<1> all(): 查詢所有結果,返回的是一個queryset物件 <2> filter(**kwargs): 它包含了與所給篩選條件相匹配的物件 <3> get(**kwargs): 返回與所給篩選條件相匹配的物件,返回結果有且只有一個, 如果符合篩選條件的物件超過一個或者沒有都會丟擲錯誤。 <4> exclude(**kwargs): 它包含了與所給篩選條件不匹配的物件 <5> order_by(*field): 對查詢結果排序 <6> reverse(): 對查詢結果反向排序 <8> count(): 返回資料庫中匹配查詢(QuerySet)的物件數量。 <9> first(): 返回第一條記錄 <10> last(): 返回最後一條記錄 <11> exists(): 如果QuerySet包含資料,就返回True,否則返回False <12> values(*field): 返回一個ValueQuerySet——一個特殊的QuerySet,執行後得到的並不是一系列 model的例項化物件,而是一個可迭代的字典序列 <13> values_list(*field): 它與values()非常相似,它返回的是一個元組序列,values返回的是一個字典序列 <14> distinct(): 從返回結果中剔除重複紀錄
在models.py的Book類中加上這兩行,讓螢幕打印出具體的書名:
def __str__(self): return self.title
例:views.py(注意可能需要重啟下django)
from django.shortcuts import render,HttpResponse # Create your views here. from app01.models import Book def index(request): # book_obj = Book.objects.create(title="Python葵花寶典", state=True, pub_date="2012-12-12", price=100, publish='人民出版社') # book_obj.save() # book_obj_2 = Book(title="Python一陽指", state=True, pub_date='2012-12-12', price=100, publish='人民出版社') # book_obj_2.save() book_list = Book.objects.all() # print(book_list) # [obj1, obj2,...] for obj in book_list: print(obj.title, obj.price) return HttpResponse("OK!!!")
螢幕列印:
Python葵花寶典 100.00
Python一陽指 100.00
再加一本書:
book_obj_2 = Book(title="Python降龍十八掌", state=True, pub_date='2015-12-12', price=200, publish='路飛出版社') book_obj_2.save()
其他的查詢API示例:(注意只要查詢結果是<QuerySet>型別的都可以繼續用相應方法呼叫,分清呼叫者和返回值)
from django.shortcuts import render,HttpResponse # Create your views here. from app01.models import Book def index(request): book_first_1 = Book.objects.all().first() # 呼叫者:queryset物件,返回值:model print("book_first:", book_first_1) book_first_2 = Book.objects.all()[2] print("book_first:", book_first_2) book_filter = Book.objects.filter(title="Python葵花寶典", price=100) # [obj1, obj2,...] print("book_filter:", book_filter) book_filter_first = Book.objects.filter(price=100).first() print("book_filter_first:", book_filter_first) book_get = Book.objects.get(price=200) # 有且只有一條結果,否則會報錯 print("book_get.pub_date:", book_get.pub_date) book_exclude = Book.objects.exclude(price=200, title="Python降龍十八掌") print("book_get.pub_date:", book_exclude) book_order_by = Book.objects.order_by("price") # "-price"表示逆序 book_order_by_1 = Book.objects.order_by("price", "-id") # 當price相等時再用id排序 print("book_order_by:", book_order_by, "book_order_by_1:", book_order_by_1) book_exists = Book.objects.all().exists() print("book_exists", book_exists) book_values = Book.objects.all().values("title") print("book_values", book_values) book_values_list = Book.objects.all().values_list("price", "title") print("book_values_list", book_values_list) book_distinct = Book.objects.all().values("price").distinct() print("book_distinct:", book_distinct) return HttpResponse("OK!!!")
對應的結果:
book_first: Python葵花寶典 book_first: Python降龍十八掌 book_filter: <QuerySet [<Book: Python葵花寶典>]> book_filter_first: Python葵花寶典 book_get.pub_date: 2015-12-12 book_get.pub_date: <QuerySet [<Book: Python葵花寶典>, <Book: Python一陽指>]> book_order_by: <QuerySet [<Book: Python葵花寶典>, <Book: Python一陽指>, <Book: Python降龍十八掌>]> book_order_by_1: <QuerySet [<Book: Python一陽指>, <Book: Python葵花寶典>, <Book: Python降龍十八掌>]> book_exists True book_values <QuerySet [{'title': 'Python葵花寶典'}, {'title': 'Python一陽指'}, {'title': 'Python降龍十八掌'}]> book_values_list <QuerySet [(Decimal('100.00'), 'Python葵花寶典'), (Decimal('100.00'), 'Python一陽指'), (Decimal('200.00'), 'Python降龍十八掌')]> book_distinct: <QuerySet [{'price': Decimal('100.00')}, {'price': Decimal('200.00')}]>
模糊查詢:
Book.objects.filter(price__in=[100, 200, 300]) Book.objects.filter(price__gt=100) # 大於100 Book.objects.filter(price__lt=100) # 小於100 Book.objects.filter(price__range=[100, 200]) Book.objects.filter(title__contains="python") # 包含 Book.objects.filter(title__icontains="python") # 不管大小寫 Book.objects.filter(title__startswith="py") Book.objects.filter(pub_date__year=2012)
刪除表記錄
Book.objects.filter(price=200).delete() # 刪除所有price=200的書 Book.objects.filter(pub_date__year=2005).delete() # Book.objects.filter(price=100).first().delete() Book.objects.filter(title="Python一陽指").update(title="Python六脈神劍")
# update只能被model物件呼叫