Python系列之Django(ORM)

ORM

基礎操作

  • 鏈接mysql數據庫

    setting.py中修改數據庫配置文件,本教程咱們以MySQL爲例

        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'orm',           # 要連接的數據庫,連接前需要創建好
            'USER': 'docker',        # 連接數據庫的用戶名
            'PASSWORD': 'docker',    # 連接數據庫的密碼
            'HOST': '127.0.0.1',     # 連接主機,默認本級
            'PORT': 3306             #  端口 默認3306
        }

    因爲django默認你導入的驅動是MySQLdb,可是MySQLdb 對於py3有很大問題,所以我們需要的驅動是PyMySQL 所以,我們只需要找到項目名文件下的init,在裏面寫入:

        import pymysql
        pymysql.install_as_MySQLdb()

    最後通過兩條數據庫遷移命令即可在指定的數據庫中創建表 :

        python manage.py makemigrations
        python manage.py migrate
  • 小技巧:如果想打印orm轉換過程中的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',
            },
        }
    }

數據表

利用Djangoorm創建數據表,不能創建數據庫,用因爲Django是基於數據表的,不是基於數據庫的。

創建數據表

我們一般在對應模塊下的model.py中創建數據表

簡單實例:

class Book(models.Model):
    '''
    創建Book數據表
    '''
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    press = models.CharField(max_length=64)
    price = models.DecimalField(max_digits=8, decimal_places=2)
    anther = models.CharField(max_length=11)

然後執行數據庫遷移即可。

添加數據

方式一:

    res = models.Book.objects.create(
        name        ="GO寶典",
        press       ="南京出版社",
        price       =1220.3,
        anther      ="Jack"
    )

方式二:

    res = Book(
        name        ="LINUX寶典",
        press       ="河南出版社",
        price       =10.3,
        anther      ="Mosson",
        text        ="String",
        email       ="[email protected]"
    )

    res.save()

查詢

基礎查詢

  • all(): 查詢所有結果
  • filter(**kwargs): 它包含了與所給篩選條件相匹配的對象
  • get(**kwargs): 返回與所給篩選條件相匹配的對象,返回結果有且只有一個,如果符合篩選條件的對象超過一個或者沒有都會拋出錯誤。
  • exclude(**kwargs): 它包含了與所給篩選條件不匹配的對象
  • order_by(*field): 對查詢結果排序
  • reverse(): 對查詢結果反向排序
  • count(): 返回數據庫中匹配查詢(QuerySet)的對象數量。
  • first(): 返回第一條記錄
  • last(): 返回最後一條記錄
  • exists(): 如果QuerySet包含數據,就返回True,否則返回False
  • values 返回一個ValueQuerySet——一個特殊的QuerySet,運行後得到的並不是一系列model的實例化對象,而是一個可迭代的字典序列(在QuertSet中存放字典序列)
Book.objects.all().values("title")
  • values_list() 它與values()非常相似,它返回的是一個元組序列,values返回的是一個字典序列(在QuertSet中存放元組序列)
Book.objects.all().values_list("title")
  • distinct 從返回結果中剔除重複紀錄(配合values和values_list使用)
Book.objects.all().distinct()

基於雙下劃線的模糊查詢 

Book.objects.filter(price__gt=10, price__lt=20)
  • 雙下劃線的查詢列表
__gt : 大於
__lt : 小於
__startswith : 以xxx開頭
__in : 在xxx之中
__contains : 包含(區分大小寫)
__icontains : 包含(不區分大小寫)
__range : 範圍

刪除

  • 刪除所有(無返回值)
model_obj.delete()
  • 條件刪除(返回刪除的ID)
Book.objects.all().values("title").delete()

修改

  • 條件修改
models.Book.objects.filter(price__gt=1000).update(name="PHP")

多表操作

創建數據

    publish_v1 = Publish.objects.get(nid=1)
    publish_v2 = Publish.objects.get(nid=2)
    publish_v3 = Publish.objects.get(nid=3)

    res = Book.objects.create(
        title       = "MacBook Pro",
        publishDate = "2018-09-18",
        price       = 12.34
    )

    res.publish.add(publish_v1, publish_v2, publish_v3)

刪除數據

    res = Book.objects.get(nid=11).delete()

查詢

  • 一對多(正向查詢):
    # 查詢主鍵爲1的書籍的出版社所在的城市
    book_obj=Book.objects.filter(pk=1).first()
    # book_obj.publish 是主鍵爲1的書籍對象關聯的出版社對象
    print(book_obj.publish.city)  
  • 一對多(反向查詢):
    res = Publish.objects.get(name="北京出版社").book_set.get(nid=12)
  • 一對一(正向查詢):
    res = Author.objects.filter(name="Alvin").first().antherDetail.telephone
  • 一對一(反向查詢):
    res = AuthorDetail.objects.filter(telephone=16621068505)
    for obj in res:
        print(obj.author.name)
  • 多對多(正向查詢):
    res = Book.objects.filter(title="PHP").first().anther.all()
    for obj in res:
        print(obj.name)
  • 多對多(反向查詢):
    res = Author.objects.filter(name="Alvin").first().book_set.all()
    for i in res:
        print(i.title)

基於雙下劃線的跨表查詢

  • 一對多(正向查詢)
    res = Book.objects.filter(publish__name="北京出版社").all()
  • 一對多(反向查詢)
    res = Publish.objects.filter(name="北京出版社").values_list("book__title")
  • 多對多(正向查詢):
    res = Book.objects.filter(title="PHP").values_list("anther__name")
  • 多對多(反向查詢):
    res = Author.objects.filter(name="Alvin").values_list("book__title")
  • 一對一(正向查詢):
    res = Author.objects.filter(name="Alvin").values_list("antherDetail__addr")
  • 一對一(反向查詢):

    res = AuthorDetail.objects.filter(author__age=23).values_list("author__name")

注:反向查詢時,如果定義了related_name ,則用related_name替換表名

聚合查詢與分組查詢

聚合(aggregate)

    res = Book.objects.filter(title="PHP").aggregate(Avg("price"))

分組(annotate)

    res = Book.objects.values("price").annotate(c=Count("*"))

附:

from django.db import models
# Create your models here.

class Book(models.Model):
    '''
    Book數據表
    '''
    nid         = models.AutoField(primary_key=True)
    title       = models.CharField( max_length=32)
    publishDate = models.DateField()
    price       = models.DecimalField(max_digits=5,decimal_places=2)

    # 與出版社表建立一對多的關係
    publish = models.ManyToManyField(to="Publish",)

    # 與Auther建立多對多的關係
    anther = models.ManyToManyField(to="Author",)

class Author(models.Model):
    '''
    Auther表
    '''
    nid     = models.AutoField(primary_key=True)
    name    = models.CharField( max_length=32)
    age     = models.IntegerField()

    # 與作者詳情表建立一對一的關係
    antherDetail = models.OneToOneField(to="AuthorDetail", on_delete=models.CASCADE)

class AuthorDetail(models.Model):
    '''
    作者詳情表
    '''
    nid         = models.AutoField(primary_key=True)
    birthday    = models.DateField()
    telephone   = models.BigIntegerField()
    addr        = models.CharField( max_length=64)

class Publish(models.Model):
    '''
    出版社表
    '''
    nid     = models.AutoField(primary_key=True)
    name    = models.CharField( max_length=32)
    city    = models.CharField( max_length=32)
    email   = models.EmailField()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章