6、Django的orm之單表操做

Django模型層(一)單表操做html

1、ORMpython

ORM是「對象-關係-映射」的簡稱。(Object Relational Mapping,簡稱ORM)mysql

orm其實就是將類對象的語法翻譯成sql語句的一個引擎sql

類對象 --- sql數據庫

類 -- 表django

對象 -- 行app

屬性 -- 字段測試

原生sql和Python的orm代碼對比:翻譯

2、Django鏈接數據庫3d

在Django項目的app應用下,有一個 models.py 文件,就是專門用來寫和數據庫相關的代碼的

  1. app01 應用下 的models.py 文件中,寫代碼來建立一個表
    from django.db import models

    # 建立表
    class Userinfo(models.Model):
    
        id = models.AutoField(primary_key=True)
        name = models.CharField(max_length=18)
        age = models.IntegerField()
        current_date = models.DateField()
    
    # 至關於:
    # create table userinfo(
    #   id int primary key auto_increment,
    #   name vachar(18),
    #   age int,
    #   current_data date
    # );
  2. 不鏈接mysql的話,默認鏈接的是sqlite數據庫,是一個小型文檔數據庫,測試的時候能夠用一下,可是在實際生產中不多用,而是用mysql
    使用sqlite的數據庫:

    第一次運行時,由於沒有安裝sqlite的驅動,是打不開數據庫的

    安裝驅動後再次打開,出現下面狀況就是運行成功了,會顯示咱們製做的表結構

    這個時候咱們就能夠添加數據了

  3. 鏈接mysql
    在配置文件settings中找到:
    DATABASES = {
    'default': {
    'ENGINE': 'django.db.backends.sqlite3',
    'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
    }

    # 修改爲:
    # 如今終端建立一個庫 orm01
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'HOST': '127.0.0.1',
            'POST': 3306,        #  端口 默認3306
            'NAME': 'orm01',
            'USER': 'root',
            'PASSWORD': '123',
    
        }
    }

    而後在項目文件夾下的 init.py 文件中加入這兩句話:
    import pymysql
    pymysql.install_as_MySQLdb() # MySQLdb是默認的鏈接數據庫的客戶端模塊,可是不支持Python3.4以上版本,因此要用pymysql把MySQLdb替換掉

    最後執行數據庫同步指令
    python manage.py makemigrations
    python manage.py migrate

    進入cmd終端進入mysql查看咱們的表是否插入進去了:

    因而可知,咱們插入表的操做算是成功的完成了!!!

3、ORM表單操做

(一)、簡單的增刪改查

類---表
類對象 --- 一行數據
類屬性 --- 字段

先建立一張表,定義四個屬性:

class Student(models.Model):
    id =  models.AutoField(primary_key=True)
    name = models.CharField(max_length=18)
    age = models.IntegerField()
    birth_date = models.DateField()

  1. 建立記錄的 方式一:

    def orm(request):
    student_obj = models.Student(
    name = 'jiege',
    age = 23,
    birth_date = '1995-01-27'
    )
    student_obj.save()
    return render(request,'myorm.html')

    建立記錄的 方式二:

    兩種方式
    一種 models.Student.objects.create(name='yuhao',...) # 關鍵字
    另外一種 models.Student.objects.create(**{'name':'liangdao',....}) # 字典打散

    def orm(request):
    new_obj = models.Student.objects.create(name='yuhao',age=25,birth_date='1995-02-06')
    print(new_obj) # Student object -- model對象
    print(new_obj.name) # 點屬性,能夠獲取對應字段的數據
    return render(request,'myorm.html')

    new_obj = models.Student.objects.create(**{'name':'liangdao','age':'25','birth_date':'1994-07-22'})
     print(new_obj)
     print(new_obj.name)
     return render(request,'myorm.html')

    建立記錄的 方式三:(批量建立,bulk_create)

    def orm(request):
    obj_list = []
    for i in range(5):
    obj = models.Student(
    name=f'xiaobai{i}',
    age=i+1,
    birth_date='2000-01-01'
    )
    obj_list.append(obj)
    models.Student.objects.bulk_create(obj_list)
    return render(request,'myorm.html')

    建立記錄的 方式四:(有就更新,沒有就建立,update_or_create)

    def orm(request):
    models.Student.objects.update_or_create(
    name='baobao',
    age=23,
    birth_date='1995-03-15'
    )
    return render(request,'myorm.html')

    添加日期的數據,要注意:

    方式一:
    models.Student.objects.create(birth_date='1996-11-15') # 字符串的形式

    方式二:
    import datetime
    now_date = datetime.datetime.now()
    models.Student.objects.create(birth_date=now_date) # 此時插入的仍然是date類型,2019-7-19 這樣

若是想打印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',
        },
    }
}  
  1. 簡單的查

    .all方法 查詢全部的數據 返回的是queryset集合

    all_objs = models.Student.objects.all()
    print(all_objs)
    # <QuerySet [<Student: Student object>, <Student: Student object>, <Student: Student object>]> -- 相似於列表 -- queryset集合

    all_objs = models.Student.objects.all()
    for i in all_objs:
    print(i.name)
    # jiege、yuhao.....,點屬性能夠取出對應的數據

    .filter方法 條件查詢 返回的也是queryset集合,查詢不到內容,不會報錯,返回一個<QuerySet []>空的queryset

    objs = models.Student.objects.filter(id=2) # 找id爲2的那條記錄
    print(objs) # <QuerySet [<Student: Student object>]>

    objs1 = models.Student.objects.filter(name='dazhuang')
    print(objs1) # <QuerySet []> 沒找到不報錯,顯示空

    objs = models.Student.objects.filter(id=2,name='yuhao')
    # 裏面的多個條件用逗號分開,而且這幾個條件必須都成立,是and的關係,or關係搞不定
    print(objs) # <QuerySet [<Student: Student object>]>

    .get方法 條件查詢 返回的是model對象,並且get方法有且必須只有1個結果

    obj = models.Student.objects.get(id=3) # 找id爲3的那條記錄
    print(obj) # model對象,Student object
    print(obj.name) # 點屬性,能夠取出對應的數據,liangdao

  2. delete方法,queryset 和model對象均可以調用

    models.Student.objects.get(id=13).delete() # model對象來調用的delete方法

    models.Student.objects.filter(age=1).delete() # queryset調用的delete方法

    models.Student.objects.all().delete() # 刪除全部

  3. update方法,

只能queryset調用

model對象不能調用更新方法 報錯信息'Student' object has no attribute 'update'

models.Student.objects.get(name='jiege').update(age=28)
# .get()返回的是model對象,不能調用update方法,會報錯

models.Student.objects.filter(name='jiege').update(age=28)
# .filter()返回的是queryset對象,能夠調用update方法

(二)、查詢接口

  • all() 查全部
    查詢全部結果,結果是queryset類型

  • filter(**kwargs) 條件查詢
    它包含了與所給篩選條件相匹配的對象,結果也是queryset類型
    models.Student.objects.filter(id=2,name='yuhao')
    # 裏面的多個條件用逗號分開,而且這幾個條件必須都成立,是and的關係,or關係搞不定

    models.Student.objects.filter(**{'id':2,'name':'yuhao'})
    # 打散形式傳參
  • get(**kwargs) 條件查詢
    返回與所給篩選條件相匹配的對象,不是queryset類型,是行記錄對象,也就是model對象,返回結果有且只有一個,
    若是符合篩選條件的對象超過一個或者沒有都會拋出錯誤。捕獲異常try。

  • exclude(**kwargs) 排除
    排除的意思,它包含了與所給篩選條件不匹配的對象,沒有不等於的操做昂,用這個exclude,返回值是queryset類型

    objects控制器和queryset集合均可以調用exclude,返回結果是queryset類型
    
    # objects控制器調用(objects後直接加exclude方法):
      query = models.Student.objects.exclude(id=1)
      print(query) # 找到除了id是1的數據
    
    # queryset集合調用
      query = models.Student.objects.filter(age=38).exclude(id=6)
      print(query) # 找到age是38,除了id是6的數據
  • order_by(*field) 排序
    queryset類型的數據來調用,對查詢結果排序,默認是按照id來升序排列的,返回值仍是queryset類型

    objs = models.Student.objects.all().order_by('age')
    # 默認是按照升序排列的,也就是按照age的升序排列
    
    objs = models.Student.objects.all().order_by('age','id')
    # 多條件的,逗號隔開,先按照age升序排列,在age相同的狀況下,按id升序排列
    
    objs = models.Student.objects.all().order_by('age','-id')
    # 降序排列,加一個'-'就能夠
  • reverse() 反轉
    queryset類型的數據來調用,對查詢結果反向排序,返回值仍是queryset類型

    # 用在排序以後反轉
    query = models.Student.objects.all().order_by('age').reverse()
    print(query)
  • count() 計數
    queryset類型的數據來調用,返回數據庫中匹配查詢(QuerySet)的對象數量。

    objs = models.Student.objects.all().count()
    print(objs)
  • first() 第一條記錄
    queryset類型的數據來調用,返回第一條記錄,獲得的都是model對象,不是queryset

    obj = models.Student.objects.all().first()
    print(obj)
  • last() 最後一條記錄
    queryset類型的數據來調用,返回最後一條記錄,結果爲model對象類型

    obj1 = models.Student.objects.all().last()
    print(obj1)
  • exists() 判斷是否包含查的數據,返回True或False
    queryset類型的數據來調用,若是QuerySet包含數據,就返回True,不然返回False

    空的queryset類型數據也有布爾值True和False,可是通常不用它來判斷數據庫裏面是否是有數據,若是有大量的數據,你用它來判斷,那麼就須要查詢出全部的數據,效率太差了,用count或者exits
    
    例:all_books = models.Book.objects.all().exists() 
    # 翻譯成的sql是SELECT (1) AS `a` FROM `app01_book` LIMIT 1,就是經過limit 1,取一條來看看是否是有數據
  • values(*field) 用的比較多 返回一個字典序列
    queryset類型的數據來調用,返回一個ValueQuerySet——一個特殊的QuerySet,運行後獲得的並非一系列model的實例化對象,而是一個可迭代的字典序列,只要是返回的queryset類型,就能夠繼續鏈式調用queryset類型的其餘的查找方法,其餘方法也是同樣的。

    obj = models.Student.objects.filter(age=25).values()
    print(obj)
    # <QuerySet [{'id': 2, 'name': 'yuhao', 'age': 25, 'birth_date': datetime.date(1995, 2, 6)}, {'id': 3, 'name': 'liangdao', 'age': 25, 'birth_date': datetime.date(1994, 7, 22)}]>
    
    obj = models.Student.objects.filter(age=25).values('name','age')
    print(obj)
    # <QuerySet [{'id': 2, 'name': 'yuhao', 'age': 25}, {'id': 3, 'name': 'liangdao', 'age': 25 }]>
  • values_list(*field) 返回一個元組序列
    它與values()很是類似,它返回的是一個元組序列,values返回的是一個字典序列

    obj = models.Student.objects.filter(age=25).values_list('name','age')
    print(obj)
    # <QuerySet [('yuhao', 25), ('liangdao', 25)]>
  • distinct() 去重
    values和values_list獲得的queryset類型的數據來調用,從返回結果中剔除重複紀錄,結果仍是queryset

    query = models.Student.objects.all().values('age').distinct()
    print(query)

(三)、基於雙下劃線的模糊查詢

1. __in=[]  值等於列表裏任意一個的對象
    obj = models.Student.objects.filter(age__in=[22,25,28])
    print(obj)
    # <QuerySet [<Student: jiege>, <Student: yuhao>, <Student: liangdao>, <Student: zhumo>]>
    
2. __gt  大於   __gte  大於等於
    obj = models.Student.objects.filter(age__gt=25)
    print(obj)
    # <QuerySet [<Student: jiege>]>
    # 注意,別寫age>25,這種參數不支持
    
3. __lt  小於   __lte  小於等於

4. __range=[]  值在一個範圍內
    obj = models.Student.objects.filter(age__range=[22,25])
    print(obj)
    # sql的between and,大於等於22,小於等於25
    
5. __contains  包含
    obj = models.Student.objects.filter(name__contains='xiao')
    print(obj)
    # name中包含xiao的
    
6. __icontains 包含,不區分大小寫
    obj = models.Student.objects.filter(name__contains='xiao')
    print(obj)
    # name中包含xiao的,不區分大小寫,好比Xiao這種也能識別出來
    
7.  __startswith  以什麼開頭   __endswith  以什麼結尾

8. __year  找日期年份相關的   __month 月份
    obj = models.Student.objects.filter(birth_date__year='1995')
    print(obj)
    # 找生日是1995年的人
    
    obj1 = models.Student.objects.filter(birth_date__year='1995',birth_date__month='01')
    print(obj1)
    # 找生日是1995年1月份的人

.

相關文章
相關標籤/搜索