【Django】Python的Django框架-數據庫查詢(增刪改查)

  • 創建項目
django-admin startproject django_model
  • 創建應用
python manage.py startapp model
  • 配置應用 model, 編輯 django_model/settings.py 文件:
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'model',
]
  • 配置Mysql數據庫:編輯 django_model/settings.py 文件, 內容如下:
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',  # mysql數據庫引擎
        'NAME': 'my_model',  # 數據庫名字
        'USER': 'root',  # 用戶名
        'PASSWORD': 'fe_cow',  # 密碼
        'HOST': 'localhost',  # 主機
        'PORT': '3306'  # 端口
    }
}
  • 創建應用所需數據庫表, 首先我們創建數據庫:
create dababase my_model charset = utf8;
  • 注意: 使用PyMysql數據庫驅動,需要在 djangomodel/_init__.py 中增加如下代碼:(python2不需要配置這項)
import pymysql 
pymysql.install_as_MySQLdb()

 

  • 定義模型

定義模型其實就是定義一個python類;一個模型類代表數據庫中一張表,一個模型類的實例代表這個數據庫表中的一條特定的記錄

from django.db import models

class Publisher(models.Model):
    """出版社"""
    name = models.CharField(max_length=30)
    address = models.CharField(max_length=50)
    city = models.CharField(max_length=60)
    country = models.CharField(max_length=50)

    def __unicode__(self):
        return self.name


class Author(models.Model):
    """作家"""
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=40)
    email = models.EmailField()

    def __unicode__(self):
        return u'%s %s' % (self.first_name, self.last_name)


class Book(models.Model):
    """書"""
    title = models.CharField(max_length=100)
    authors = models.ManyToManyField(Author) # 書和作者是多對多的關係
    publisher = models.ForeignKey(Publisher) # 書和出版者是多對一的關係
    publication_date = models.DateField()

    def __unicode__(self):
        return self.title
  • 定義完模型後,要執行數據庫遷移操作:

先執行python manage.py makemigrations 在執行:python manage.py migrate
一張表中定義了多對多的關係,ORM會自動創建實現多對多關係的第三張表。

 

數據庫的操作:

通過python shell 來演示數據庫的操作。在終端切換到項目根目錄下,輸入命令python manage.py shell 進入shell操作環境。
增刪改查

1 創建記錄

方法一:實例化(調用save()方法之前,Django不會訪問數據庫;save()方法沒有返回值)

>>> from apps.models import Author
>>> author = Author(last_name='fe_cow')
>>> author.save()
>>> print author
 fe_cow

方法二:create() (只用一條語句創建並保存一個對象,使用create()方法。)

>>> Author.objects.create(first_name='fe',last_name='cow', email='[email protected]')

方法三:get_or_create(), 這種方法可以防止重複(速度稍慢,因爲會先查數據庫), 它返回一個元組。創建成功返回True,失敗的話False,不執行創建。

>>> author = Author.objects.get_or_create(last_name='fe_cow')
>>> print author
(<Author:  fe_cow>, False)  # False:說明已經重複 創建失敗
>>> author = Author.objects.get_or_create(last_name='cu_cow')
>>> print author
(<Author:  cu_cow>, True)  # True: 創建成功


2 查詢記錄

方法一:查詢所有對象 (all()方法返回包含數據庫中所有對象的一個查詢集。)

>>> author = Author.objects.all()
>>> print author
<QuerySet [<Author:  fecow>, <Author:  fe_cow>, <Author: fe cow>, <Author: fe cow>, <Author: fe cow>, <Author: fe cow>, <Author:  cu_cow>]>


方法二:過濾查詢 (filter()返回一個新的查詢集,它包含滿足查詢參數的對象。)

>>> author = Author.objects.filter(last_name='cu_cow')
>>> print author
<QuerySet [<Author:  cu_cow>]>


方法三:指定查詢 (get查詢只能返回一個對象,多了少了都會引發DoesNotExist 異常)

>>> author = Author.objects.get(id=1)
>>> print author
 fecow


方法四:雙下劃線查詢__;__contains:包含;__icontains不區分大小寫;__regex:正則查詢;__lt:小於xxx;__lte:小於等於xxx;__gt:大於xxx;__gte:大於等於xxx;__startswith(): 以xxx開頭,;__istartswith():不區分大小寫以xxx開頭, __endswith():以xxx結尾;__iendswith():以xxx結尾不區分大小寫

以上使用方法基本上都一致:對象.objects.filter(屬性 __xxx) 例子如下:

>>> author = Author.objects.filter(id__gte=2)
>>> print author
<QuerySet [<Author:  fe_cow>, <Author: fe cow>, <Author: fe cow>, <Author: fe cow>, <Author: fe cow>, <Author:  cu_cow>]>

單獨說一個特殊的__in 判斷字段在列表內。通常用pk指主鍵,不限於id,適用更好。

>>> author_list = Author.objects.values_list('id', flat=True)
# 返回的是:<QuerySet [1L, 2L, 3L, 4L, 5L, 6L, 7L]>
>>> Author.objects.filter(pk__in=author)
<QuerySet [<Author:  fe_cow>, <Author: fe cow>, <Author: fe cow>, <Author: fe cow>, <Author: fe cow>, <Author:  cu_cow>]>

方法五:first(), last()獲取查詢結果中單個對象

>>> Author.objects.filter(id__gte=2)
# 返回結果:QuerySet集合
<QuerySet [<Author:  fe_cow>, <Author: fe cow>, <Author: fe cow>, <Author: fe cow>, <Author: fe cow>, <Author:  cu_cow>]>
>>> Author.objects.filter(id__gte=2).first()
# 返回結果:objects對象  而且返回第一個對象
<Author:  fe_cow>
>>> Author.objects.filter(id__gte=2).last()
<Author:  cu_cow>
# 返回結果:objects對象 而且返回的是最後一個對象

方法六:通過values查詢

values('字段')用字典形式,返回的是指定字段的查詢結果;

>>> Author.objects.values('last_name')
<QuerySet [{'last_name': u'fecow'}, {'last_name': u'fe_cow'}, {'last_name': u'cow'}, {'last_name': u'cow'}, {'last_name': u'cow'}, {'last_name': u'cow'}, {'last_name': u'cu_cow'}]>
# 返回字典列表;多個字段間以逗號分隔

values_list('字典'),返回的也是指定字段的查詢結果

>>> Author.objects.values_list('last_name')
<QuerySet [(u'fecow',), (u'fe_cow',), (u'cow',), (u'cow',), (u'cow',), (u'cow',), (u'cu_cow',)]>
# 返回的是元組列表,多個字段也是用逗號分割

values_list('字段', flat=True) flat=True :之後返回的是值列表

>>> Author.objects.values_list('id', flat=True)
<QuerySet [1L, 2L, 3L, 4L, 5L, 6L, 7L]>
# 返回的是列表

方法六:exclude(**kwargs)反向過濾

>>> Author.objects.exclude(id__gt=2)
<QuerySet [<Author:  fecow>, <Author:  fe_cow>]>
# 取反

方法七:exists()

>>> Author.objects.filter(id=2).exists()
True
#  QuerySet包含數據返回True
>>> Author.objects.filter(last_name='Au_cow').exists()
False
#  QuerySet不包含數據返回False


3 修改記錄

方法一:QuerySet.update('字段'='修改的值')

>>> Author.objects.filter(last_name='cu_cow').update(last_name='Ai_cow')
1L
# 修改的前提是先查找,然後調用update(field=val)方法,只有QuerySet集合對象才能調用該方法,也就是說通過get(), first(), last()獲取的對象沒有該方法。

方法二:對象賦值

>>> author_obj = Author.objects.filter(last_name='fe_cow').first()
>>> author_obj.last_name = 'Fe_cow'
>>> author_obj.save()
# 不推薦使用,效率低


4 刪除記錄

調用delete()方法 delete()方法支持QuerySet集合對象的刪除,也支持單個對象的刪除。

>>> Author.objects.filter(last_name='fe_cow').delete()
(1L, {u'apps.Book_authors': 0L, u'apps.Author': 1L})
# 默認就是級聯刪除,對應多對多的表也會刪除

QuerySet

通過名字我們也能想到從數據庫查出來的結果一般是一個集合,哪怕只有一個對象,也叫集合。
QuerySet特性

可以進行切片,也可以進行遍歷。

>>> Author.objects.filter(id__gt=2)[:2]  # 使用切片來獲取
# <QuerySet [<Author: fe cow>, <Author: fe cow>]>
>>> authors = Author.objects.filter(id__gt=2)  # 使用for循環來獲取
>>> for author in authors:
...     print author 
# 打印結果如下
# fe cow 
# fe cow
# fe cow
# fe cow

惰性機制: 只有使用QuerySet時,纔會走數據庫。像.all() filter()時,並不會真正執行數據庫查詢,只是翻譯了SQL語句;當我們執行if xxx ,print xxx; for xxx in xxx:這些操作纔會執行SQL語句,進行數據庫查詢。
緩存機制:每次執行了數據庫查詢後,會將結果放在QuerySet的緩存中,下次在使用QuerySet時, 不會走數據庫,直接從緩存中拿取數據。比如:

>>> author = Author.objects.all()  # 獲取所有Author QuerySet中的 last_name
>>> for res in author:
...     print res.last_name  # Ai_cow  cow

>>> Author.objects.create(last_name='COW',first_name='FE')  # 接下來往數據庫中插入一跳數據
>>>for res in author:
        print res.last_name  # Ai_cow  cow   # 發現,已經創建了新的數據,但是表裏面沒有這條數據
# 以上結果證明了QuerySet緩存的機制,新添加一條記錄;打印結果沒有發生改變,說明他不會重新走數據庫,而是從緩存中獲取數據。
>>> author = Author.objects.all()  # 獲取所有Author QuerySet中的 last_name
>>> for res in author:
...     print res.last_name  # Ai_cow  cow COW

 

 


————————————————
版權聲明:本文爲CSDN博主「Fe_cow丿」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/Fe_cow/article/details/80669146

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章