Django 模型層

ORM簡介

  • MVC或者MVC框架中包括一個重要的部分,就是ORM,它實現了數據模型與數據庫的解耦,即數據模型的設計不須要依賴於特定的數據庫,經過簡單的配置就能夠輕鬆更換數據庫,這極大的減輕了開發人員的工做量,不須要面對因數據庫變動而致使的無效勞動。
  • ORM是「對象-關係-映射」的簡稱。

字段與參數

每一個字段有一些特有的參數,例如,CharField須要max_length參數來指定VARCHAR數據庫字段的大小。還有一些適用於全部字段的通用參數。 這些參數在文檔中有詳細定義,這裏咱們只簡單介紹一些最經常使用的:php

1、字段

    AutoField(Field)
        - int自增列,必須填入參數 primary_key=True

    BigAutoField(AutoField)
        - bigint自增列,必須填入參數 primary_key=True

        注:當model中若是沒有自增列,則自動會建立一個列名爲id的列
        from django.db import models

        class UserInfo(models.Model):
            # 自動建立一個列名爲id的且爲自增的整數列
            username = models.CharField(max_length=32)

        class Group(models.Model):
            # 自定義自增列
            nid = models.AutoField(primary_key=True)
            name = models.CharField(max_length=32)

    SmallIntegerField(IntegerField):
        - 小整數 -32768 ~ 32767

    PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
        - 正小整數 0 ~ 32767
    IntegerField(Field)
        - 整數列(有符號的) -2147483648 ~ 2147483647

    PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
        - 正整數 0 ~ 2147483647

    BigIntegerField(IntegerField):
        - 長整型(有符號的) -9223372036854775808 ~ 9223372036854775807

    自定義無符號整數字段

        class UnsignedIntegerField(models.IntegerField):
            def db_type(self, connection):
                return 'integer UNSIGNED'

        PS: 返回值爲字段在數據庫中的屬性,Django字段默認的值爲:
            'AutoField': 'integer AUTO_INCREMENT',
            'BigAutoField': 'bigint AUTO_INCREMENT',
            'BinaryField': 'longblob',
            'BooleanField': 'bool',
            'CharField': 'varchar(%(max_length)s)',
            'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
            'DateField': 'date',
            'DateTimeField': 'datetime',
            'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
            'DurationField': 'bigint',
            'FileField': 'varchar(%(max_length)s)',
            'FilePathField': 'varchar(%(max_length)s)',
            'FloatField': 'double precision',
            'IntegerField': 'integer',
            'BigIntegerField': 'bigint',
            'IPAddressField': 'char(15)',
            'GenericIPAddressField': 'char(39)',
            'NullBooleanField': 'bool',
            'OneToOneField': 'integer',
            'PositiveIntegerField': 'integer UNSIGNED',
            'PositiveSmallIntegerField': 'smallint UNSIGNED',
            'SlugField': 'varchar(%(max_length)s)',
            'SmallIntegerField': 'smallint',
            'TextField': 'longtext',
            'TimeField': 'time',
            'UUIDField': 'char(32)',

    BooleanField(Field)
        - 布爾值類型

    NullBooleanField(Field):
        - 能夠爲空的布爾值

    CharField(Field)
        - 字符類型
        - 必須提供max_length參數, max_length表示字符長度

    TextField(Field)
        - 文本類型

    EmailField(CharField):
        - 字符串類型,Django Admin以及ModelForm中提供驗證機制

    IPAddressField(Field)
        - 字符串類型,Django Admin以及ModelForm中提供驗證 IPV4 機制

    GenericIPAddressField(Field)
        - 字符串類型,Django Admin以及ModelForm中提供驗證 Ipv4和Ipv6
        - 參數:
            protocol,用於指定Ipv4或Ipv6, 'both',"ipv4","ipv6"
            unpack_ipv4, 若是指定爲True,則輸入::ffff:192.0.2.1時候,可解析爲192.0.2.1,開啓刺功能,須要protocol="both"

    URLField(CharField)
        - 字符串類型,Django Admin以及ModelForm中提供驗證 URL

    SlugField(CharField)
        - 字符串類型,Django Admin以及ModelForm中提供驗證支持 字母、數字、下劃線、鏈接符(減號)

    CommaSeparatedIntegerField(CharField)
        - 字符串類型,格式必須爲逗號分割的數字

    UUIDField(Field)
        - 字符串類型,Django Admin以及ModelForm中提供對UUID格式的驗證

    FilePathField(Field)
        - 字符串,Django Admin以及ModelForm中提供讀取文件夾下文件的功能
        - 參數:
                path,                      文件夾路徑
                match=None,                正則匹配
                recursive=False,           遞歸下面的文件夾
                allow_files=True,          容許文件
                allow_folders=False,       容許文件夾

    FileField(Field)
        - 字符串,路徑保存在數據庫,文件上傳到指定目錄
        - 參數:
            upload_to = ""      上傳文件的保存路徑
            storage = None      存儲組件,默認django.core.files.storage.FileSystemStorage

    ImageField(FileField)
        - 字符串,路徑保存在數據庫,文件上傳到指定目錄
        - 參數:
            upload_to = ""      上傳文件的保存路徑
            storage = None      存儲組件,默認django.core.files.storage.FileSystemStorage
            width_field=None,   上傳圖片的高度保存的數據庫字段名(字符串)
            height_field=None   上傳圖片的寬度保存的數據庫字段名(字符串)

    DateTimeField(DateField)
        - 日期+時間格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]

    DateField(DateTimeCheckMixin, Field)
        - 日期格式      YYYY-MM-DD

    TimeField(DateTimeCheckMixin, Field)
        - 時間格式      HH:MM[:ss[.uuuuuu]]

    DurationField(Field)
        - 長整數,時間間隔,數據庫中按照bigint存儲,ORM中獲取的值爲datetime.timedelta類型

    FloatField(Field)
        - 浮點型

    DecimalField(Field)
        - 10進制小數
        - 參數:
            max_digits,小數總長度
            decimal_places,小數位長度

    BinaryField(Field)
        - 二進制類型
字段

2、參數

    null                數據庫中字段是否能夠爲空
    db_column           數據庫中字段的列名
    db_tablespace
    default             數據庫中字段的默認值
    primary_key         數據庫中字段是否爲主鍵
    db_index            數據庫中字段是否能夠創建索引
    unique              數據庫中字段是否能夠創建惟一索引
    unique_for_date     數據庫中字段【日期】部分是否能夠創建惟一索引
    unique_for_month    數據庫中字段【月】部分是否能夠創建惟一索引
    unique_for_year     數據庫中字段【年】部分是否能夠創建惟一索引

    verbose_name        Admin中顯示的字段名稱
    blank               Admin中是否容許用戶輸入爲空
    editable            Admin中是否能夠編輯
    help_text           Admin中該字段的提示信息
    choices             Admin中顯示選擇框的內容,用不變更的數據放在內存中從而避免跨表操做
                        如:gf = models.IntegerField(choices=[(0, '何穗'),(1, '大表姐'),],default=1)

    error_messages      自定義錯誤信息(字典類型),從而定製想要顯示的錯誤信息;
                        字典健:null, blank, invalid, invalid_choice, unique, and unique_for_date
                        如:{'null': "不能爲空.", 'invalid': '格式錯誤'}

    validators          自定義錯誤驗證(列表類型),從而定製想要的驗證規則
                        from django.core.validators import RegexValidator
                        from django.core.validators import EmailValidator,URLValidator,DecimalValidator,\
                        MaxLengthValidator,MinLengthValidator,MaxValueValidator,MinValueValidator
                        如:
                            test = models.CharField(
                                max_length=32,
                                error_messages={
                                    'c1': '優先錯信息1',
                                    'c2': '優先錯信息2',
                                    'c3': '優先錯信息3',
                                },
                                validators=[
                                    RegexValidator(regex='root_\d+', message='錯誤了', code='c1'),
                                    RegexValidator(regex='root_112233\d+', message='又錯誤了', code='c2'),
                                    EmailValidator(message='又錯誤了', code='c3'), ]
                            )
參數

3、元信息

class UserInfo(models.Model):
    nid = models.AutoField(primary_key=True)
    username = models.CharField(max_length=32)

    class Meta:
        # django之後再作數據庫遷移時,再也不爲UserInfo類建立相關的表以及表結構了。
        # 此類能夠當作"父類",被其餘Model類繼承。
        abstract = True

        # 數據庫中生成的表名稱 默認 app名稱 + 下劃線 + 類名
        db_table = "table_name"

        # 聯合索引
        index_together = [
            ("pub_date", "deadline"),
        ]

        # 聯合惟一索引
        unique_together = (("driver", "restaurant"),)

        # admin中顯示的表名稱
        verbose_name

        # verbose_name加s
        verbose_name_plural


更多:https: // docs.djangoproject.com / en / 1.10 / ref / models / options /
元信息

4、連表結構

ForeignKey(ForeignObject) # ForeignObject(RelatedField)
        to,                         # 要進行關聯的表名
        to_field=None,              # 要關聯的表中的字段名稱
        on_delete=None,             # 當刪除關聯表中的數據時,當前表與其關聯的行的行爲
                                        - models.CASCADE,刪除關聯數據,與之關聯也刪除
                                        - models.DO_NOTHING,刪除關聯數據,引起錯誤IntegrityError
                                        - models.PROTECT,刪除關聯數據,引起錯誤ProtectedError
                                        - models.SET_NULL,刪除關聯數據,與之關聯的值設置爲null(前提FK字段須要設置爲可空)
                                        - models.SET_DEFAULT,刪除關聯數據,與之關聯的值設置爲默認值(前提FK字段須要設置默認值)
                                        - models.SET,刪除關聯數據,
                                                      a. 與之關聯的值設置爲指定值,設置:models.SET(值)
                                                      b. 與之關聯的值設置爲可執行對象的返回值,設置:models.SET(可執行對象)

                                                        def func():
                                                            return 10

                                                        class MyModel(models.Model):
                                                            user = models.ForeignKey(
                                                                to="User",
                                                                to_field="id"
                                                                on_delete=models.SET(func),)
        related_name=None,          # 反向操做時,使用的字段名,用於代替 【表名_set】 如: obj.表名_set.all()
        related_query_name=None,    # 反向操做時,使用的鏈接前綴,用於替換【表名】     如: models.UserGroup.objects.filter(表名__字段名=1).values('表名__字段名')
        limit_choices_to=None,      # 在Admin或ModelForm中顯示關聯數據時,提供的條件:
                                    # 如:
                                            - limit_choices_to={'nid__gt': 5}
                                            - limit_choices_to=lambda : {'nid__gt': 5}

                                            from django.db.models import Q
                                            - limit_choices_to=Q(nid__gt=10)
                                            - limit_choices_to=Q(nid=8) | Q(nid__gt=10)
                                            - limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
        db_constraint=True          # 是否在數據庫中建立外鍵約束
        parent_link=False           # 在Admin中是否顯示關聯數據


    OneToOneField(ForeignKey)
        to,                         # 要進行關聯的表名
        to_field=None               # 要關聯的表中的字段名稱
        on_delete=None,             # 當刪除關聯表中的數據時,當前表與其關聯的行的行爲

                                    ###### 對於一對一 ######
                                    # 1. 一對一其實就是 一對多 + 惟一索引
                                    # 2.當兩個類之間有繼承關係時,默認會建立一個一對一字段
                                    # 以下會在A表中額外增長一個c_ptr_id列且惟一:
                                            class C(models.Model):
                                                nid = models.AutoField(primary_key=True)
                                                part = models.CharField(max_length=12)

                                            class A(C):
                                                id = models.AutoField(primary_key=True)
                                                code = models.CharField(max_length=1)

    ManyToManyField(RelatedField)
        to,                         # 要進行關聯的表名
        related_name=None,          # 反向操做時,使用的字段名,用於代替 【表名_set】 如: obj.表名_set.all()
        related_query_name=None,    # 反向操做時,使用的鏈接前綴,用於替換【表名】     如: models.UserGroup.objects.filter(表名__字段名=1).values('表名__字段名')
        limit_choices_to=None,      # 在Admin或ModelForm中顯示關聯數據時,提供的條件:
                                    # 如:
                                            - limit_choices_to={'nid__gt': 5}
                                            - limit_choices_to=lambda : {'nid__gt': 5}

                                            from django.db.models import Q
                                            - limit_choices_to=Q(nid__gt=10)
                                            - limit_choices_to=Q(nid=8) | Q(nid__gt=10)
                                            - limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
        symmetrical=None,           # 僅用於多對多自關聯時,symmetrical用於指定內部是否建立反向操做的字段
                                    # 作以下操做時,不一樣的symmetrical會有不一樣的可選字段
                                        models.BB.objects.filter(...)

                                        # 可選字段有:code, id, m1
                                            class BB(models.Model):

                                            code = models.CharField(max_length=12)
                                            m1 = models.ManyToManyField('self',symmetrical=True)

                                        # 可選字段有: bb, code, id, m1
                                            class BB(models.Model):

                                            code = models.CharField(max_length=12)
                                            m1 = models.ManyToManyField('self',symmetrical=False)

        through=None,               # 自定義第三張表時,使用字段用於指定關係表
        through_fields=None,        # 自定義第三張表時,使用字段用於指定關係表中那些字段作多對多關係表

        db_constraint = True,       # 是否在數據庫中建立外鍵約束
        db_table = None,            # 默認建立第三張表時,數據庫中表的名稱


                                        from django.db import models

                                        class Person(models.Model):
                                            name = models.CharField(max_length=50)

                                        class Group(models.Model):
                                            name = models.CharField(max_length=128)
                                            members = models.ManyToManyField(
                                                Person,
                                                through='Membership',
                                                through_fields=('group', 'person'),
                                            )

                                        class Membership(models.Model):
                                            group = models.ForeignKey(Group, on_delete=models.CASCADE)
                                            person = models.ForeignKey(Person, on_delete=models.CASCADE)
                                            inviter = models.ForeignKey(
                                                Person,
                                                on_delete=models.CASCADE,
                                                related_name="membership_invites",
                                            )
                                            invite_reason = models.CharField(max_length=64)

"""
與普通的多對多不同,使用自定義中間表的多對多不能使用add(), create(),remove(),和set()方法來建立、刪除關係
beatles = Group.objects.create(name="The Beatles")
>>> # 無效
>>> beatles.members.add(john)
>>> # 無效
>>> beatles.members.create(name="George Harrison")
>>> # 無效
>>> beatles.members.set([john, paul, ringo, george])
可是,clear()方法是有效的,它能清空全部的多對多關係。
>>> # 有效
>>> beatles.members.clear()
一旦經過建立中間模型實例的方法創建了多對多的關聯,你馬上就能夠像普通的多對多那樣進行查詢操做:
"""
連表結構

5、雙下劃線

# 獲取個數
        #
        # models.Tb1.objects.filter(name='seven').count()

        # 大於,小於
        #
        # models.Tb1.objects.filter(id__gt=1)              # 獲取id大於1的值
        # models.Tb1.objects.filter(id__gte=1)              # 獲取id大於等於1的值
        # models.Tb1.objects.filter(id__lt=10)             # 獲取id小於10的值
        # models.Tb1.objects.filter(id__lte=10)             # 獲取id小於10的值
        # models.Tb1.objects.filter(id__lt=10, id__gt=1)   # 獲取id大於1 且 小於10的值

        # in
        #
        # models.Tb1.objects.filter(id__in=[11, 22, 33])   # 獲取id等於十一、2二、33的數據
        # models.Tb1.objects.exclude(id__in=[11, 22, 33])  # not in

        # isnull
        # Entry.objects.filter(pub_date__isnull=True)

        # contains
        #
        # models.Tb1.objects.filter(name__contains="ven")
        # models.Tb1.objects.filter(name__icontains="ven") # icontains大小寫不敏感
        # models.Tb1.objects.exclude(name__icontains="ven")

        # range
        #
        # models.Tb1.objects.filter(id__range=[1, 2])   # 範圍bettwen and

        # 其餘相似
        #
        # startswith,istartswith, endswith, iendswith,

        # order by
        #
        # models.Tb1.objects.filter(name='seven').order_by('id')    # asc
        # models.Tb1.objects.filter(name='seven').order_by('-id')   # desc

        # group by
        #
        # from django.db.models import Count, Min, Max, Sum
        # models.Tb1.objects.filter(c1=1).values('id').annotate(c=Count('num'))
        # SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id"

        # limit 、offset
        #
        # models.Tb1.objects.all()[10:20]

        # regex正則匹配,iregex 不區分大小寫
        #
        # Entry.objects.get(title__regex=r'^(An?|The) +')
        # Entry.objects.get(title__iregex=r'^(an?|the) +')

        # date
        #
        # Entry.objects.filter(pub_date__date=datetime.date(2005, 1, 1))
        # Entry.objects.filter(pub_date__date__gt=datetime.date(2005, 1, 1))

        # year
        #
        # Entry.objects.filter(pub_date__year=2005)
        # Entry.objects.filter(pub_date__year__gte=2005)

        # month
        #
        # Entry.objects.filter(pub_date__month=12)
        # Entry.objects.filter(pub_date__month__gte=6)

        # day
        #
        # Entry.objects.filter(pub_date__day=3)
        # Entry.objects.filter(pub_date__day__gte=3)

        # week_day
        #
        # Entry.objects.filter(pub_date__week_day=2)
        # Entry.objects.filter(pub_date__week_day__gte=2)

        # hour
        #
        # Event.objects.filter(timestamp__hour=23)
        # Event.objects.filter(time__hour=5)
        # Event.objects.filter(timestamp__hour__gte=12)

        # minute
        #
        # Event.objects.filter(timestamp__minute=29)
        # Event.objects.filter(time__minute=46)
        # Event.objects.filter(timestamp__minute__gte=29)

        # second
        #
        # Event.objects.filter(timestamp__second=31)
        # Event.objects.filter(time__second=2)
        # Event.objects.filter(timestamp__second__gte=31)
進階操做
# extra
    #
    # extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None)
    #    Entry.objects.extra(select={'new_id': "select col from sometable where othercol > %s"}, select_params=(1,))
    #    Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
    #    Entry.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'"])
    #    Entry.objects.extra(select={'new_id': "select id from tb where id > %s"}, select_params=(1,), order_by=['-nid'])

    # F
    #
    # from django.db.models import F
    # models.Tb1.objects.update(num=F('num')+1)


    # Q
    #
    # 方式一:
    # Q(nid__gt=10)
    # Q(nid=8) | Q(nid__gt=10)
    # Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
    # 方式二:
    # con = Q()
    # q1 = Q()
    # q1.connector = 'OR'
    # q1.children.append(('id', 1))
    # q1.children.append(('id', 10))
    # q1.children.append(('id', 9))
    # q2 = Q()
    # q2.connector = 'OR'
    # q2.children.append(('c1', 1))
    # q2.children.append(('c1', 10))
    # q2.children.append(('c1', 9))
    # con.add(q1, 'AND')
    # con.add(q2, 'AND')
    #
    # models.Tb1.objects.filter(con)


    # 執行原生SQL
    #
    # from django.db import connection, connections
    # cursor = connection.cursor()  # cursor = connections['default'].cursor()
    # cursor.execute("""SELECT * from auth_user where id = %s""", [1])
    # row = cursor.fetchone()
其餘操做
on_delete=None,               # 刪除關聯表中的數據時,當前表與其關聯的field的行爲
on_delete=models.CASCADE,     # 刪除關聯數據,與之關聯也刪除
on_delete=models.DO_NOTHING,  # 刪除關聯數據,什麼也不作
on_delete=models.PROTECT,     # 刪除關聯數據,引起錯誤ProtectedError
# models.ForeignKey('關聯表', on_delete=models.SET_NULL, blank=True, null=True)
on_delete=models.SET_NULL,    # 刪除關聯數據,與之關聯的值設置爲null(前提FK字段須要設置爲可空,一對一同理)
# models.ForeignKey('關聯表', on_delete=models.SET_DEFAULT, default='默認值')
on_delete=models.SET_DEFAULT, # 刪除關聯數據,與之關聯的值設置爲默認值(前提FK字段須要設置默認值,一對一同理)
on_delete=models.SET,         # 刪除關聯數據,
————————————————
版權聲明:本文爲CSDN博主「buxianghejiu」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接及本聲明。
原文連接:https://blog.csdn.net/buxianghejiu/article/details/79086011
on_delete

單表操做

1、建立表

一、建立模型

建立名爲app01的app,在app01下的models.py中建立模型:html

?
1
2
3
4
5
6
7
8
9
10
11
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 ) # 999999.99
      publish = models.CharField(max_length = 32 )
 
      def __str__( self ):
          return self .title

二、settings配置:DATABASES

若想將模型轉爲mysql數據庫中的表,須要在settings中配置:前端

?
1
2
3
4
5
6
7
8
9
10
DATABASES = {
     'default' : {
         'ENGINE' : 'django.db.backends.mysql' ,
         'NAME' : 'orm9' , # 要鏈接的數據庫,鏈接前須要建立好
         'USER' : 'root' , # 鏈接數據庫的用戶名
         'PASSWORD' :'', # 鏈接數據庫的密碼
         'HOST' : '127.0.0.1' , # 鏈接主機,默認本級
         'PORT' : 3306 , # 端口 默認3306
     }
}

三、settings配置:INSTALLED_APPS

確保配置文件中的INSTALLED_APPS中寫入咱們建立的app名稱python

?
1
2
3
4
5
6
7
8
9
INSTALLED_APPS = [
     'django.contrib.admin' ,
     'django.contrib.auth' ,
     'django.contrib.contenttypes' ,
     'django.contrib.sessions' ,
     'django.contrib.messages' ,
     'django.contrib.staticfiles' ,
     "app01" ,
]

四、項目名文件下的__init__配置

django默認導入的驅動是MySQLdb,但是MySQLdb 對於py3有很大問題,咱們須要的驅動是PyMySQL 因此,咱們只須要找到項目名文件下的__init__,在裏面寫入:mysql

?
1
2
import pymysql
pymysql.install_as_MySQLdb()

五、數據庫遷移命令

?
1
2
python manage.py makemigrations
python manage.py migrate

六、靜態文件配置:

?
1
2
3
4
5
#在settings.py中:
STATIC_URL = '/static/'
STATICFILES_DIRS = (
     os.path.join(BASE_DIR, 'static' ),
)

七、打印orm轉換過程當中的sql,在settings中配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
LOGGING = {
     'version' : 1 ,
     'disable_existing_loggers' : False ,
     'handlers' : {
         'console' :{
             'level' : 'DEBUG' ,
             'class' : 'logging.StreamHandler' ,
         },
     },
     'loggers' : {
         'django.db.backends' : {
             'handlers' : [ 'console' ],
             'propagate' : True ,
             'level' : 'DEBUG' ,
         },
     }
}  

八、常見報錯

  • 報錯:no module named MySQLdb 。這是由於django默認你導入的驅動是MySQLdb,但是MySQLdb 對於py3有很大問題,因此咱們須要的驅動是PyMySQL 因此,咱們只須要找到項目名文件下的__init__,在裏面寫入:
?
1
2
import pymysql
pymysql.install_as_MySQLdb()
  • 報錯:django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.3 or newer is required; you have 0.7.11.None
  • MySQLclient目前只支持到python3.4,所以若是使用的更高版本的python,須要修改以下: 經過查找路徑C:\Programs\Python\Python36-32\Lib\site-packages\Django-2.0-py3.6.egg\django\db\backends\mysql 這個路徑裏的文件把下面代碼註釋掉就OK了。
?
1
2
if version < ( 1 , 3 , 3 ):
      raise ImproperlyConfigured( "mysqlclient 1.3.3 or newer is required; you have %s" % Database.__version__)

2、增

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#app01.views.py
from django.shortcuts import render,HttpResponse
from app01.models import Book
def index(request):
     # ==================================添加表記錄 ==================================
  
     # 方式1:
     # book_obj=Book(id=1,title="python",price=100,pub_date="2012-12-12",publish="人民出版社")
     # book_obj.save()
  
     #方式2: create返回值就是當前生成的對象紀錄
  
     book_obj = Book.objects.create(title = "php2" ,price = 100 ,pub_date = "2013-12-12" ,publish = "人民出版社" )
     print (book_obj.title)
     print (book_obj.price)
     print (book_obj.pub_date)
     return HttpResponse( "OK" )
     
     #方式3: 批量導入:
     
     book_list = []
     for i in range ( 100 ):
         book = Book(title = "book_%s" % i,price = i * i)
         book_list.append(book)
 
     Book.objects.bulk_create(book_list)

3、刪

  • 在 Django 刪除對象時,會模仿 SQL 約束 ON DELETE CASCADE 的行爲,換句話說,刪除一個對象時也會刪除與它相關聯的外鍵對象。
  • 若是不想級聯刪除,能夠設置爲:pubHouse = models.ForeignKey(to='Publisher', on_delete=models.SET_NULL, blank=True, null=True)
  • delete() 方法是 QuerySet 上的方法,但並不適用於 Manager 自己。這是一種保護機制,是爲了不意外地調用 Entry.objects.delete() 方法致使 全部的 記錄被誤刪除。若是你確認要刪除全部的對象,那麼你必須顯式地調用:Entry.objects.all().delete() 
?
1
2
3
4
5
6
7
8
9
10
11
#app01.views.py
from django.shortcuts import render,HttpResponse
from app01.models import Book
def index(request):
     # ==================================刪除表紀錄=================================
     # delete: 調用者: queryset對象  model對象
     ret = Book.objects. filter (price = 100 ).delete()
     print (ret)
     ret2 = Book.objects. filter (price = 100 ).first().delete()
     print (ret2)
     return HttpResponse( "OK" )

4、改

update()方法對於任何結果集(QuerySet)均有效,你能夠同時更新多條記錄update()方法會返回一個整型數值,表示受影響的記錄條數。git

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#app01.views.py
from django.shortcuts import render,HttpResponse
from app01.models import Book
def index(request):
     # ==================================修改表紀錄 =================================
     # update :  調用者: queryset對象
 
     #方式1
     book_obj = Book.objects.get(pk = 1 )
     book_obj.title = '新值'
     book_obj.save()
 
     #方式2
     ret = Book.objects. filter (title = "php2" ).update(title = "php" )
     return HttpResponse( "OK" )

5、查

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#app01.views.py
from django.shortcuts import render,HttpResponse
from app01.models import Book
def index(request):
     # ================================== 查詢表記錄API ==================================
     
     #(1) all方法:   返回值一個queryset對象                      ## 查詢全部結果
     #book_list=Book.objects.all()
     #print(book_list)  # [obj1,obj2,.....]
 
     # for  obj in book_list:
     #     print(obj.title,obj.price)
     #print(book_list[1].title)
 
     #(2) first,last : 調用者:queryset對象  返回值:model對象     ## first:返回第一條記錄  last:返回最後一條記錄
     #book=Book.objects.all().first()
     #book=Book.objects.all()[0]
 
     #(3) filter()  返回值:queryset對象                          ## 它包含了與所給篩選條件相匹配的對象
     # book_list=Book.objects.filter(price=100)     # [obj1,obj2,....]
     # print(book_list) #<QuerySet [<Book: python>, <Book: php>]>
     # book_obj=Book.objects.filter(price=100).first()
 
     # ret=Book.objects.filter(title="go",price=200)
     # print(ret)
 
     #(4) get()  有且只有一個查詢結果時纔有意義  返回值:model對象  ## 若是符合篩選條件的對象超過一個或者沒有都會拋出錯誤。
     # book_obj=Book.objects.get(title="go")
     # book_obj=Book.objects.get(price=100)
     # print(book_obj.price)
 
     # (5) exclude 返回值:queryset對象                            ##它包含了與所給篩選條件不匹配的對象 與filter() 相反
     # ret=Book.objects.exclude(title="go")
     # print(ret)
 
     # (6) order_by   調用者: queryset對象   返回值:  queryset對象  ## 對查詢結果排序
     # ret=Book.objects.all().order_by("-id")
     # ret=Book.objects.all().order_by("price","id")
     # print(ret)
 
     # (7) count()   調用者: queryset對象   返回值: int           ##返回數據庫中匹配查詢(QuerySet)的對象數量。
     # ret=Book.objects.all().count()
     # print(ret)
 
     # (8) exist()                                                ##若是QuerySet包含數據,就返回True,不然返回False
     # ret=Book.objects.all().exists()
     #
     # if ret:
     #     print("ok")
 
     # (9) values 方法  調用者: queryset對象  返回值:queryset對象
     # ret=Book.objects.all()
     # for i in ret:
     #     print(i.title)
     # ret=Book.objects.all().values("price","title")
     # print(ret)
     '''
     values:
     temp=[]
 
     for obj in Book.objects.all()
          temp.append({
              "price"=obj.price
              "title"=obj.title
          })
     return temp
     '''
     # <QuerySet [{'price': Decimal('100.00')}, {'price': Decimal('100.00')}, {'price': Decimal('200.00')}]>
     #print(ret[0].get("price")) # 100.00
 
     # (10) values_list 方法  調用者: queryset對象  返回值:queryset對象
     # ret=Book.objects.all().values_list("price","title")
     # # print(ret) #<QuerySet [(Decimal('100.00'),), (Decimal('100.00'),), (Decimal('200.00'),)]>
     # print(ret)
 
     '''
values:
     <QuerySet [{'title': 'python紅寶書', 'price': Decimal('100.00')}, {'title': 'php', 'price': Decimal('100.00')}, {'title': 'go', 'price': Decimal('200.00')}]>
values_list:
     <QuerySet [(Decimal('100.00'), 'python紅寶書'), (Decimal('100.00'), 'php'), (Decimal('200.00'), 'go')]>
 
     '''
     # 11 distinct                                       ##從返回結果中剔除重複紀錄  reverse對查詢結果反向排序
     # ret=Book.objects.all().distinct()   #沒有意義
     # ret=Book.objects.all().values("price").distinct()
 
     #Book.objects.all().filter().order_by().filter().reverse().first()
 
     # ================================== 基於雙下劃線的模糊查詢 ==================================
 
     # ret=Book.objects.filter(price__gt=10,price__lt=200)
 
     # ret=Book.objects.filter(title__startswith="p")
 
     #ret=Book.objects.filter(title__contains="h")
     #ret=Book.objects.filter(title__icontains="h")  #忽略大小寫
 
     #ret=Book.objects.filter(price__in=[100,200,300])
 
     #ret=Book.objects.filter(price__range=[200,300])
 
     #ret=Book.objects.filter(pub_date__year=2018,pub_date__month=5)
 
     return HttpResponse( "OK" )

6、聚合查詢與分組查詢

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# app01.models.py
 
from django.db import models
 
 
class Emp(models.Model):
     name = models.CharField(max_length = 32 )
     age = models.IntegerField()
     salary = models.DecimalField(max_digits = 8 , decimal_places = 2 )
     dep = models.CharField(max_length = 32 )
     province = models.CharField(max_length = 32 )
 
 
# app01.views.py
 
from django.shortcuts import render, HttpResponse
from app01.models import *
from django.db.models import Avg, Max , Min , Count
 
 
def query(request):
     # -------------------------單表 聚合與分組查詢---------------------------
 
     # ------------------------->聚合 aggregate:返回值是一個字典,再也不是queryset
     # 查詢全部書籍的平均價格
     ret = Book.objects. all ().aggregate(avg_price = Avg( "price" ), max_price = Max ( "price" ))
     print (ret)  # {'avg_price': 151.0, 'max_price': Decimal('301.00')}
 
     ret = Book.objects.aggregate(Avg( 'price' ), Max ( 'price' ), Min ( 'price' ))
     print (ret)  # {'price__avg': 151.0, 'price__max': Decimal('301.00'), 'price__min': Decimal('12.99')}
 
     # ------------------------->分組查詢 annotate ,返回值依然是queryset
     # 單表分組查詢的ORM語法: 單表模型.objects.values("group by的字段").annotate(聚合函數("統計字段"))
     # 在單表分組下, 按着主鍵進行group by是沒有任何意義的.
 
     # 查詢每個部門的名稱以及員工的平均薪水
     # select dep,Avg(salary) from emp group by dep
 
     ret = Emp.objects.values( "dep" ).annotate(avg_salary = Avg( "salary" ))
     print (ret)  # <QuerySet [{'avg_salary': 5000.0, 'dep': '保安部'}, {'avg_salary': 51000.0, 'dep': '教學部'}]>
 
     # 查詢每個省份的名稱以及員工數
     ret = Emp.objects.values( "province" ).annotate(c = Count( "id" ))
     print (ret)  # <QuerySet [{'province': '山東省', 'c': 2}, {'province': '河北省', 'c': 1}]>
 
     # 補充知識點:
     # ret=Emp.objects.all()
     # print(ret)  # select * from emp
     # ret=Emp.objects.values("name")
     # print(ret)  # select name from emp
 
     return HttpResponse( 'OK' )

多表操做

1、建立表

  • id字段是自動添加的
  • 對於外鍵字段,Django 會在字段名上添加"_id" 來建立數據庫中的列名
  • 外鍵字段 ForeignKey 有一個 null=True 的設置(它容許外鍵接受空值 NULL),你能夠賦給它空值 None 。
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
from django.db import models
 
# Create your models here.
from django.db import models
'''
Book  ----   Publish 一對多
 
'''
class Author(models.Model):
     nid = models.AutoField(primary_key = True )
     name = models.CharField( max_length = 32 )
     age = models.IntegerField()
     # 一對一
     authordetail = models.OneToOneField(to = "AuthorDetail" ,to_field = "nid" ,on_delete = models.CASCADE)
     def __str__( self ):
         return self .name
 
# 做者詳情表
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()
 
     def __str__( self ):
         return self .name
 
class Book(models.Model):
     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.ForeignKey(to = "Publish" ,to_field = "nid" ,on_delete = models.CASCADE,)
     '''
         publish_id INT ,
         FOREIGN KEY (publish_id) REFERENCES publish(id)
 
     '''
 
     #多對多
     authors = models.ManyToManyField(to = "Author" )
 
     '''
     CREATE  TABLE book_authors(
        id INT PRIMARY KEY auto_increment ,
        book_id INT ,
        author_id INT ,
        FOREIGN KEY (book_id) REFERENCES book(id),
        FOREIGN KEY (author_id) REFERENCES author(id)
         )
     '''
 
# class Book2Author(models.Model):
#
#     nid = models.AutoField(primary_key=True)
#     book=models.ForeignKey(to="Book")
#     author=models.ForeignKey(to="Author")
 
     def __str__( self ):
         return self .title

2、增

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
from django.shortcuts import render, HttpResponse
from app01.models import *
def add(request):
     # -------------------------一對多的關係-------------------------
     #方式1:
     #爲book表綁定出版社: book  ---    publish
     book_obj = Book.objects.create(title = "紅樓夢" ,price = 100 ,publishDate = "2012-12-12" ,publish_id = 1 )
     print (book_obj.title)
 
     #方式2: 
     #pub_obj = Publish.objects.get(nid=1)
     pub_obj = Publish.objects. filter (nid = 1 ).first()
     book_obj = Book.objects.create(title = "三國演繹" ,price = 100 ,publishDate = "2012-12-12" ,publish = pub_obj)
     print (book_obj.publish)       #  與這本書籍關聯的出版社對象
     print (book_obj.publish_id)
 
     # -------------------------多對多的關係-------------------------
     book_obj = Book.objects.create(title = "python全棧開發" ,price = 100 ,publishDate = "2012-12-12" ,publish_id = 1 )
 
     egon = Author.objects.get(name = "egon" )
     alex = Author.objects.get(name = "alex" )
 
     #綁定多對多關係的API
     book_obj.authors.add(egon,alex)
     book_obj.authors.add( 1 , 2 , 3 )
     book_obj.authors.add( * [ 1 , 2 , 3 ])
 
     #解除多對多關係
     book_obj = Book.objects. filter (nid = 4 ).first()
     book_obj.authors.remove( 2 )
     #book_obj.authors.remove(*[1,2])  # 將某個特定的對象從被關聯對象集合中去除。
 
     book_obj.authors.clear()    # 清空被關聯對象集合
     book_obj.authors. set ()  # 先清空再設置 
     return HttpResponse( "OK" )

3、刪

?
1
2
3
def delete_book(request,delete_book_id):
     Book.objects. filter (pk = delete_book_id).delete()
     return redirect( "/books/" )

4、改

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
def change_book(request,edit_book_id):
     edit_book_obj = Book.objects. filter (pk = edit_book_id).first()
 
     if  request.method = = "POST" :
         title = request.POST.get( "title" )
         price = request.POST.get( "price" )
         pub_date = request.POST.get( "pub_date" )
         
         # 多對一
         publish_id = request.POST.get( "publish_id" )
         #多對多
         authors_id_list = request.POST.getlist( "authors_id_list" ) # checkbox,select
 
         Book.objects. filter (pk = edit_book_id).update(title = title,price = price,publishDate = pub_date,publish_id = publish_id)
         # edit_book_obj.authors.clear()
         # edit_book_obj.authors.add(*authors_id_list)
 
         #多對多
         edit_book_obj.authors. set (authors_id_list)
 
         return redirect( "/books/" )
 
     publish_list = Publish.objects. all ()
     author_list = Author.objects. all ()
 
     return render(request, "editbook.html" ,{ "edit_book_obj" :edit_book_obj, "publish_list" :publish_list, "author_list" :author_list})

5、查

一、基於對象的跨表查詢(子查詢)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
A - B
關聯屬性在A表中
 
正向查詢: A - - - - - - >B
反向查詢: B - - - - - - >A
 
基於對象的跨表查詢(子查詢)
     # 一對多查詢
            正向查詢:按字段
            反向查詢:表名小寫_set. all ()
 
                                      book_obj.publish
             Book(關聯屬性:publish)對象  - - - - - - - - - - - - - - > Publish對象
                                      < - - - - - - - - - - - - - -
                                  publish_obj.book_set. all ()  # queryset
 
     # 多對多查詢
            正向查詢:按字段
            反向查詢:表名小寫_set. all ()
 
                                      book_obj.authors. all ()
             Book(關聯屬性:authors)對象  - - - - - - - - - - - - - - - - - - - - - - - - > Author對象
                                      < - - - - - - - - - - - - - - - - - - - - - - - -
                                      author_obj.book_set. all () # queryset
 
     # 一對一查詢
            正向查詢:按字段
            反向查詢:表名小寫
 
                                               author.authordetail
             Author(關聯屬性:authordetail)對象  - - - - - - - - - - - - - - - - - - - - - - - - >AuthorDetail對象
                                              < - - - - - - - - - - - - - - - - - - - - - - - -
                                               authordetail.author
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
from django.shortcuts import render, HttpResponse
from app01.models import *
 
def query(request):
     # -------------------------基於對象的跨表查詢(子查詢)-----------------------
 
     # 一對多查詢的正向查詢 : 查詢python全棧開發這本書的出版社的名字
     book_obj = Book.objects. filter (title = "python全棧開發" ).first()
     print (book_obj.publish) # 與這本書關聯的出版社對象
     print (book_obj.publish.name)
 
     # 一對多查詢的反向查詢 : 查詢人民出版社出版過的書籍名稱
     publish = Publish.objects. filter (name = "人民出版社" ).first()
     ret = publish.book_set. all ()
     print (ret)
 
     # 多對多查詢的正向查詢 : 查詢python全棧開發這本書的全部做者的名字
     book_obj = Book.objects. filter (title = "python全棧開發" ).first()
     author_list = book_obj.authors. all () # queryset對象  [author_obj1,...]
 
     for author in author_list:
         print (author.name)
 
     # 多對多查詢的反向查詢 : 查詢alex出版過的全部書籍名稱
     alex = Author.objects. filter (name = "alex" ).first()
 
     book_list = alex.book_set. all ()
     for book in book_list:
         print (book.title)
 
 
     # 一對一查詢的正向查詢 : 查詢alex的手機號
     alex = Author.objects. filter (name = "alex" ).first()
     print (alex.authordetail.telephone)
 
     # 一對一查詢的反向查詢 : 查詢手機號爲110的做者的名字和年齡
     ad = AuthorDetail.objects. filter (telephone = "110" ).first()
     print (ad.author.name)
     print (ad.author.age)
 
     return HttpResponse( "ok" )

二、基於雙下劃線的跨表查詢

?
1
2
3
4
5
6
7
8
A - B
關聯屬性在A表中
 
正向查詢: A - - - - - - >B
反向查詢: B - - - - - - >A
 
基於雙下劃線的跨表查詢(join查詢)
      key:正向查詢按字段,反向查詢按表名小寫
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
from django.shortcuts import render, HttpResponse
from app01.models import *
 
def query(request):
 
     # -------------------------基於雙下劃線的跨表查詢(join查詢)-----------------------
 
     '''
     正向查詢按字段,反向查詢按表名小寫用來告訴ORM引擎join哪張表
     '''
 
     # 一對多查詢 : 查詢python全棧開發這本書的出版社的名字
     # 方式1:
     ret = Book.objects. filter (title = "python全棧開發" ).values( "publish__name" )
     print (ret) # <QuerySet [{'publish__name': '南京出版社'}]>
 
     # 方式2:
     ret = Publish.objects. filter (book__title = "python全棧開發" ).values( "name" )
     print (ret)
 
     # 多對多查詢 : 查詢python全棧開發這本書的全部做者的名字
     # 方式1:
     # 需求: 經過Book表join與其關聯的Author表,屬於正向查詢:按字段authors通知ORM引擎join book_authors與author
     ret = Book.objects. filter (title = "python全棧開發" ).values( "authors__name" )
     print (ret) # <QuerySet [{'authors__name': 'alex'}, {'authors__name': 'egon'}]>
 
     # 方式2:
     # 需求: 經過Author表join與其關聯的Book表,屬於反向查詢:按表名小寫book通知ORM引擎join book_authors與book表
     ret = Author.objects. filter (book__title = "python全棧開發" ).values( "name" )
     print (ret) # <QuerySet [{'name': 'alex'}, {'name': 'egon'}]>
 
     # 一對一查詢的查詢 : 查詢alex的手機號
     # 方式1:
     # 需求: 經過Author表join與其關聯的AuthorDetail表,屬於正向查詢:按字段authordetail通知ORM引擎join Authordetail表
     ret = Author.objects. filter (name = "alex" ).values( "authordetail__telephone" )
     print (ret) # <QuerySet [{'authordetail__telephone': 110}]>
 
     # 方式2:
     # 需求: 經過AuthorDetail表join與其關聯的Author表,屬於反向查詢:按表名小寫author通知ORM引擎join Author表
     ret = AuthorDetail.objects. filter (author__name = "alex" ).values( "telephone" )
     print (ret) # <QuerySet [{'telephone': 110}]>
 
     # 進階練習:(連續跨表)
     # 練習: 手機號以110開頭的做者出版過的全部書籍名稱以及書籍出版社名稱
 
     # 方式1:
     # 需求: 經過Book表join AuthorDetail表, Book與AuthorDetail無關聯,因此必需連續跨表
     ret = Book.objects. filter (authors__authordetail__telephone__startswith = "110" ).values( "title" , "publish__name" )
     print (ret)
 
     # 方式2:
     ret = Author.objects. filter (authordetail__telephone__startswith = "110" ).values( "book__title" , "book__publish__name" )
     print (ret)
 
     return HttpResponse( "OK" )

三、聚合和分組查詢

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
from django.shortcuts import render, HttpResponse
from app01.models import *
 
def query(request):
      # ------------------------->聚合 aggregate:返回值是一個字典,再也不是queryset
     # 查詢全部書籍的平均價格
     from django.db.models import Avg, Max , Min , Count
     ret = Book.objects. all ().aggregate(avg_price = Avg( "price" ), max_price = Max ( "price" ))
     print (ret)  # {'avg_price': 151.0, 'max_price': Decimal('301.00')}
 
     ret = Book.objects.aggregate(Avg( 'price' ), Max ( 'price' ), Min ( 'price' ))
     print (ret)  # {'price__avg': 151.0, 'price__max': Decimal('301.00'), 'price__min': Decimal('12.99')}
 
     # ------------------------->多表分組查詢 annotate ,返回值依然是queryset
     # 單表總結: objects.values("group by的字段").annotate(聚合函數("統計字段"))
 
     # 多表總結:跨表的分組查詢的模型:
     # 方式1:每個後的表模型.objects.values("pk").annotate(聚合函數(關聯表__統計字段)).values("表模型的全部字段以及統計字段")
     # 方式2:每個後的表模型.objects.annotate(聚合函數(關聯表__統計字段)).values("表模型的全部字段以及統計字段")
 
 
      #################### 方式1: 跨表分組查詢####################
 
     #查詢每個出版社的名稱以及出版的書籍個數
     #法1:
     ret = Publish.objects.values( "name" ).annotate(c = Count( "book__title" ))
     print (ret)  # <QuerySet [{'name': '人民出版社', 'c': 3}, {'name': '南京出版社', 'c': 1}]>
 
     ret = Publish.objects.values( "nid" ).annotate(c = Count( "book__title" ))
     print (ret)  # <QuerySet [{'nid': 1, 'c': 3}, {'nid': 2, 'c': 1}]>
 
     # 法2:
     ret = Publish.objects.values( "nid" ).annotate(c = Count( "book__title" )).values( "name" , "c" )
     print (ret)  # <QuerySet [{'name': '人民出版社', 'c': 3}, {'name': '南京出版社', 'c': 1}]>
 
     #查詢每個做者的名字以及出版過的書籍的最高價格
     ret = Author.objects.values( "pk" ).annotate(max_price = Max ( "book__price" )).values( "name" , "max_price" )
     print (ret)
 
     #查詢每個書籍的名稱以及對應的做者個數
     ret = Book.objects.values( "pk" ).annotate(c = Count( "authors__name" )).values( "title" , "c" )
     print (ret)
 
     #################### 方式2: 跨表分組查詢####################
 
     # 示例1 查詢每個出版社的名稱以及出版的書籍個數
     # ret=Publish.objects.values("nid").annotate(c=Count("book__title")).values("name","email","c")
     # ret=Publish.objects.all().annotate(c=Count("book__title")).values("name","c","city")
     ret = Publish.objects.annotate(c = Count( "book__title" )).values( "name" , "c" , "city" )
     print (ret)
 
     ##################### 練習   ####################
 
     # 統計每一本以py開頭的書籍的做者個數:
     # 每個後的表模型.objects.values("pk").annotate(聚合函數(關聯表__統計字段)).values("表模型的全部字段以及統計字段")
     ret = Book.objects. filter (title__startswith = "py" ).values( "pk" ).annotate(c = Count( "authors__name" )).values( "title" , "c" )
 
     # 統計不止一個做者的圖書
     ret = Book.objects.values( "pk" ).annotate(c = Count( "authors__name" )). filter (c__gt = 1 ).values( "title" , "c" )
     print (ret)
 
     #根據一本圖書做者數量的多少對查詢集 QuerySet進行排序:
     ret = Book.objects.annotate(num_authors = Count( 'authors' )).order_by( 'num_authors' )
 
     return HttpResponse( "查詢成功" )

四、F 與 Q查詢

使用F表達式引用模型的字段sql

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
from django.shortcuts import render, HttpResponse
from app01.models import *
from django.db.models import F,Q
 
def query(request):
     #################### F查詢####################
     #兩個字段的值作比較, F() 的實例能夠在查詢中引用字段,來比較同一個 model 實例中兩個不一樣字段的值。
 
     # 查詢評論數大於收藏數的書籍
     Book.objects. filter (commnetNum__lt = F( 'keepNum' ))
 
     # 查詢評論數大於收藏數2倍的書籍
     Book.objects. filter (commnetNum__lt = F( 'keepNum' ) * 2 )
 
     #修改操做也可使用F函數,好比將每一本書的價格提升30元:
     Book.objects. all ().update(price = F( "price" ) + 30 )
 
     ####################Q查詢####################
     #filter() 等方法中的關鍵字參數查詢都是一塊兒進行「AND」 的。 若是你須要執行更復雜的查詢(例如OR 語句),你可使用Q 對象。
 
     #Q對象可使用& 和| 操做符組合起來。當一個操做符在兩個Q 對象上使用時,它產生一個新的Q 對象。
     bookList = Book.objects. filter (Q(authors__name = "yuan" ) | Q(authors__name = "egon" ))
     #sql ...WHERE name ="yuan" OR name ="egon"
 
     #Q對象可使用~ 操做符取反,這容許組合正常的查詢和取反(NOT) 查詢:
     bookList = Book.objects. filter (Q(authors__name = "yuan" ) & ~Q(publishDate__year = 2017 )).values_list( "title" )
 
     #混合使用Q對象和關鍵字參數。全部提供給查詢函數的參數(關鍵字參數或Q 對象)都將"AND」在一塊兒。可是,若是出現Q 對象,它必須位於全部關鍵字參數的前面。
     bookList = Book.objects. filter (Q(publishDate__year = 2016 ) | Q(publishDate__year = 2017 ),
                                    title__icontains = "python"
                                    )
     return HttpResponse( "查詢成功" )

五、extra

有些狀況下,Django的查詢語法難以簡單的表達複雜的 WHERE 子句,對於這種狀況, Django 提供了 extra() QuerySet修改機制 它能在 QuerySet生成的SQL從句中注入新子句,extra能夠指定一個或多個 參數,例如 select, where or tables.這些參數都不是必須的,可是你至少要使用一個!要注意這些額外的方式對不一樣的數據庫引擎可能存在移植性問題.(由於你在顯式的書寫SQL語句),除非萬不得已,儘可能避免這樣作.數據庫

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# 每個後的表模型.objects.values("pk").annotate(聚合函數(關聯表__統計字段)).values("表模型的全部字段以及統計字段")
 
# 查詢每個分類名稱以及對應的文章數
ret = models.Category.objects.values( "pk" ).annotate(c = Count( "article__title" )).values( "title" , "c" )
 
# 查詢當前站點的每個分類名稱以及對應的文章數
cate_list = models.Category.objects. filter (blog = blog).values( "pk" ).annotate(c = Count( "article__title" )).values_list( "title" , "c" )
 
# 查詢當前站點的每個標籤名稱以及對應的文章數
tag_list = models.Tag.objects. filter (blog = blog).values( "pk" ).annotate(c = Count( "article" )).values_list( "title" , "c" )
 
# 查詢當前站點每個年月的名稱以及對應的文章數
 
"""
extra(select=None, where=None, params=None, tables=None, order_by=None, select_params=None)
 
參數之select
         The select 參數可讓你在 SELECT 從句中添加其餘字段信息,它應該是一個字典,存放着屬性名到 SQL 從句的映射。
         queryResult=models.Article
                    .objects.extra(select={'is_recent': "create_time > '2017-09-05'"})
         結果集中每一個 Entry 對象都有一個額外的屬性is_recent, 它是一個布爾值,表示 Article對象的create_time 是否晚於2017-09-05.
"""
 
 
ret = models.Article.objects.extra(select = { "is_recent" : "create_time > '2018-09-05'" }).values( "title" , "is_recent" )
# 方式1:
# mysql
date_list = models.Article.objects. filter (user = user).extra(select = { "y_m_date" : "date_format(create_time,'%%Y/%%m')" }
                                                          ).values( "y_m_date" ).annotate(c = Count( "nid" )).values_list( "y_m_date" , "c" )
# sqlite
date_list = models.Article.objects. filter (user = user).extra(select = { "y_m_date" : "strftime('%%Y/%%m',create_time)" }
                                                          ).values( "y_m_date" ).annotate(c = Count( "nid" )).values_list( "y_m_date" , "c" )
 
# 方式2:
from django.db.models.functions import TruncMonth
ret = models.Article.objects. filter (user = user).annotate(month = TruncMonth( "create_time" )).values( "month" ).annotate(c = Count( "nid" )).values_list( "month" , "c" )
 
# 日期歸檔查詢的方式2
from django.db.models.functions import TruncMonth
"""
Sales.objects
.annotate(month=TruncMonth('timestamp'))  # Truncate to month and add to select list
.values('month')  # Group By month
.annotate(c=Count('id'))  # Select the count of the grouping
.values('month', 'c')  # (might be redundant, haven't tested) select month and count
"""
 
"""
參數之where
"""
val = "2018-10"
# mysql
all_count = models.Article.objects. filter (blog = blog).extra(
     where = [ 'date_format(create_time,"%%Y-%%m")=%s' ], params = [val, ]).count()
article_list = models.Article.objects. filter (blog = blog).extra(
     where = [ 'date_format(create_time,"%%Y-%%m")=%s' ], params = [val, ])[page_info.start():page_info.end()]
# sqlite
all_count = models.Article.objects. filter (blog = blog).extra(
     where = [ 'strftime("%%Y-%%m",create_time)=%s' ], params = [val, ]).count()
article_list = models.Article.objects. filter (blog = blog).extra(
     where = [ 'strftime("%%Y-%%m",create_time)=%s' ], params = [val, ])[page_info.start():page_info.end()]
 
#直接寫sql語句
# mysql
cursor = connection.cursor()
sql = 'select count(1) as nm,date_format(create_time,"%%Y-%%m") as ctime from article where blog_id= %s group by date_format(create_time,"%%Y-%%m")'
cursor.execute(sql,(blog.nid,))
date_list = cursor.fetchall()
# sqlite
date_list = models.Article.objects.raw(
     'select nid, count(1) as num,strftime("%Y-%m",create_time) as ctime from article group by strftime("%Y-%m",create_time)' )

六、pk

主鍵的快捷查詢方式:pkdjango

七、blog

from django.db import models


# from django.contrib.auth.models import AbstractUser
# class UserInfo(AbstractUser):
#     """
#     用戶信息
#     """
#     nid = models.AutoField(primary_key=True)
#     telephone = models.CharField(max_length=11, null=True, unique=True)
#     avatar = models.FileField(upload_to='avatars/', default="avatars/default.png")
#     create_time = models.DateTimeField(verbose_name='建立時間', auto_now_add=True)
#
#     blog = models.OneToOneField(to='Blog', to_field='nid', null=True, on_delete=models.CASCADE)
#
#     def __str__(self):
#         return self.username
#
#     class Meta:
#         verbose_name = '我的博客信息'
#         verbose_name_plural = '博客信息'


class UserInfo(models.Model):
    """
    用戶表
    """
    nid = models.BigAutoField(primary_key=True)
    username = models.CharField(verbose_name='用戶名', max_length=32, unique=True)
    password = models.CharField(verbose_name='密碼', max_length=64)
    nickname = models.CharField(verbose_name='暱稱', max_length=32)
    email = models.EmailField(verbose_name='郵箱', unique=True)

    avatar = models.FileField(verbose_name='頭像',upload_to='avatars/', default="avatars/default.png")
    # 被傳到`MEDIA_ROOT/uploads/2015/01/30`目錄,增長了一個時間劃分
    # avatar = models.FileField(upload_to='uploads/%Y/%m/%d/')

    create_time = models.DateTimeField(verbose_name='建立時間', auto_now_add=True)

    fans = models.ManyToManyField(verbose_name='粉絲們',
                                  to='UserInfo',
                                  through='UserFans',
                                  related_name='f',
                                  through_fields=('user', 'follower'))
    class Meta:
        verbose_name = '我的博客信息'
        verbose_name_plural = '博客信息'


class Blog(models.Model):
    """
    博客信息
    """
    nid = models.BigAutoField(primary_key=True)
    title = models.CharField(verbose_name='我的博客標題', max_length=64)
    site = models.CharField(verbose_name='站點名稱', max_length=32, unique=True)
    theme = models.CharField(verbose_name='博客主題', max_length=32)
    user = models.OneToOneField(to='UserInfo', to_field='nid',on_delete=models.CASCADE)

    theme_choices = [
        ('default', "默認主題"),
        ('bule', "藍色主題"),
        ('red', "紅色主題"),
    ]

    def __str__(self):

        return self.title

    class Meta:
        verbose_name = '我的博客信息'
        verbose_name_plural = '博客信息'

class UserFans(models.Model):
    """
    互粉關係表
    """
    user = models.ForeignKey(
        verbose_name='博主', to='UserInfo', to_field='nid', related_name='users',on_delete=models.CASCADE
    )
    follower = models.ForeignKey(
        verbose_name='粉絲', to='UserInfo', to_field='nid', related_name='followers',on_delete=models.CASCADE
    )

    class Meta:
        verbose_name = '互粉關係'
        verbose_name_plural = '互粉關係'
        unique_together = [
            ('user', 'follower'),
        ]

class Category(models.Model):
    """
    博主我的文章分類表
    """
    nid = models.AutoField(primary_key=True)
    title = models.CharField(verbose_name='分類標題', max_length=32)
    parent = models.ForeignKey(verbose_name='父ID', to='Category', to_field='nid', on_delete=models.CASCADE, null=True)
    blog = models.ForeignKey(verbose_name='所屬博客', to='Blog', to_field='nid',on_delete=models.CASCADE)
    class Meta:
        verbose_name = '文章分類'
        verbose_name_plural = '文章分類'

class ArticleDetail(models.Model):
    """
    文章詳細表
    """
    content = models.TextField(verbose_name='文章內容', )

    article = models.OneToOneField(verbose_name='所屬文章', to='Article', to_field='nid',on_delete=models.CASCADE)

    class Meta:
        verbose_name = '文章詳細'
        verbose_name_plural = '文章詳細'

class UpDown(models.Model):
    """
    文章頂或踩
    """
    article = models.ForeignKey(verbose_name='文章', to='Article', to_field='nid',on_delete=models.CASCADE)
    user = models.ForeignKey(verbose_name='贊或踩用戶', to='UserInfo', to_field='nid',on_delete=models.CASCADE)
    up = models.BooleanField(verbose_name='是否贊')

    class Meta:
        verbose_name = '文章頂踩'
        verbose_name_plural = '文章頂踩'
        unique_together = [
            ('article', 'user'),
        ]


class Comment(models.Model):
    """
    評論表
    """
    nid = models.BigAutoField(primary_key=True)
    content = models.CharField(verbose_name='評論內容', max_length=255)
    create_time = models.DateTimeField(verbose_name='建立時間', auto_now_add=True)

    reply = models.ForeignKey(verbose_name='回覆評論', to='self', related_name='back', null=True,on_delete=models.CASCADE)
    article = models.ForeignKey(verbose_name='評論文章', to='Article', to_field='nid',on_delete=models.CASCADE)
    user = models.ForeignKey(verbose_name='評論者', to='UserInfo', to_field='nid',on_delete=models.CASCADE)
    class Meta:
        verbose_name = '文章評論'
        verbose_name_plural = '文章評論'

class Tag(models.Model):
    nid = models.AutoField(primary_key=True)
    title = models.CharField(verbose_name='標籤名稱', max_length=32)
    blog = models.ForeignKey(verbose_name='所屬博客', to='Blog', to_field='nid',on_delete=models.CASCADE)
    class Meta:
        verbose_name = '文章標籤'
        verbose_name_plural = '文章標籤'


class Article(models.Model):
    nid = models.BigAutoField(primary_key=True)
    title = models.CharField(verbose_name='文章標題', max_length=128)
    summary = models.CharField(verbose_name='文章簡介', max_length=255)
    read_count = models.IntegerField(default=0)
    comment_count = models.IntegerField(default=0)
    up_count = models.IntegerField(default=0)
    down_count = models.IntegerField(default=0)
    create_time = models.DateTimeField(verbose_name='建立時間', auto_now_add=True)

    blog = models.ForeignKey(verbose_name='所屬博客', to='Blog', to_field='nid',on_delete=models.CASCADE)
    category = models.ForeignKey(verbose_name='文章類型', to='Category', to_field='nid', null=True,on_delete=models.CASCADE)

    type_choices = [
        (1, "編程語言"),
        (2, "操做系統"),
        (3, "Web前端"),
        (4, "數據庫"),
        (5, "English"),
        (6, "其餘分類"),
    ]

    article_type_id = models.IntegerField(choices=type_choices, default=None)

    tags = models.ManyToManyField(
        to="Tag",
        through='Article2Tag',
        through_fields=('article', 'tag'),
    )

    class Meta:
        verbose_name = '文章信息'
        verbose_name_plural = '文章信息'

class Article2Tag(models.Model):
    article = models.ForeignKey(verbose_name='文章', to="Article", to_field='nid',on_delete=models.CASCADE)
    tag = models.ForeignKey(verbose_name='標籤', to="Tag", to_field='nid',on_delete=models.CASCADE)

    class Meta:
        verbose_name = '文章與標籤'
        verbose_name_plural = '文章與標籤'
        unique_together = [
            ('article', 'tag'),
        ]


class Tpl(models.Model):
    user = models.ForeignKey(UserInfo, on_delete=models.CASCADE)
    title = models.CharField(max_length=32)
    content = models.TextField()


class Trouble(models.Model):
    title = models.CharField(max_length=32)
    detail = models.TextField()
    user = models.ForeignKey(UserInfo,related_name='u',on_delete=models.CASCADE)
    # ctime = models.CharField(max_length=32) # 1491527007.452494
    ctime = models.DateTimeField()
    status_choices = (
        (1,'未處理'),
        (2,'處理中'),
        (3,'已處理'),
    )
    status = models.IntegerField(choices=status_choices,default=1)

    processer = models.ForeignKey(UserInfo,related_name='p',null=True,blank=True,on_delete=models.CASCADE)
    solution = models.TextField(null=True)
    ptime = models.DateTimeField(null=True)
    pj_choices = (
        (1, '不滿意'),
        (2, '通常'),
        (3, '很滿意'),
    )
    pj = models.IntegerField(choices=pj_choices,null=True,default=2)


"""
form中:
from django.forms import fields
    theme = fields.ChoiceField(
        choices=models.Blog.theme_choices,
        widget=widgets.Select(attrs={'class': 'form-control'})
    )
模板中:
{{ form.theme }}


models中:
    status_choices = (
        (1,'未處理'),
        (2,'處理中'),
        (3,'已處理'),
    )
    status = models.IntegerField(choices=status_choices,default=1)
    ptime = models.DateTimeField(null=True,blank=True)

views中:
    dic['ptime'] = datetime.datetime.now()

模板中:
{% for row in result %}
<td>{{ row.get_status_display }}</td>
{% endfor %}


models中:
    type_choices = [
        (1, "編程語言"),
        (2, "操做系統"),
        (3, "Web前端"),
        (4, "數據庫"),
        (5, "English"),
        (6, "其餘分類"),
    ]

views:
    article_type_list = models.Article.type_choices

"""
blog models
import os

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "about_contenttype.settings")

    import django
    django.setup()

    from app01.models import Post, Picture, Comment
    from django.contrib.auth.models import User
    # 準備測試數據
    user_1 = User.objects.create_user(username='aaa', password='123')
    user_2 = User.objects.create_user(username='bbb', password='123')
    user_3 = User.objects.create_user(username='ccc', password='123')

    post_1 = Post.objects.create(author=user_1, title='Python入門教程')
    post_2 = Post.objects.create(author=user_2, title='Python進階教程')
    post_3 = Post.objects.create(author=user_1, title='Python入土教程')

    picture_1 = Picture.objects.create(author=user_1, image='小姐姐01.jpg')
    picture_2 = Picture.objects.create(author=user_1, image='小姐姐02.jpg')
    picture_3 = Picture.objects.create(author=user_3, image='小哥哥01.jpg')

    # 給帖子建立評論數據
    comment_1 = Comment.objects.create(author=user_1, content='好文!', content_object=post_1)
    # 給圖片建立評論數據
    comment_2 = Comment.objects.create(author=user_2, content='好美!', content_object=picture_1)
django.setup()

6、模板

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
<!--查看全部 views.py 傳過來的book_list    book_list=Book.objects.all()-->
< tbody >
               {% for book in book_list %}
               < tr >
                    < td >{{ forloop.counter }}</ td >
                    < td >{{ book.title }}</ td >
                    < td >{{ book.price }}</ td >
                    < td >{{ book.publishDate|date:"Y-m-d" }}</ td >
                    < td >
                        {{ book.publish.name }}
                    </ td >
                    < td >
                        {% for author in book.authors.all %}
                           {% if forloop.last %}
                            < span >{{ author.name }}</ span >
                           {% else %}
                            < span >{{ author.name }}</ span >,
                           {% endif %}
                        {% endfor %}
                    </ td >
                    < td >
                        < a href="/books/{{ book.pk }}/change/" class="btn btn-warning">編輯</ a >
                        < a href="/books/{{ book.pk }}/delete/" class="btn btn-danger">刪除</ a >
                    </ td >
               </ tr >
               {% endfor %}
</ tbody >
 
 
<!--編輯  views.py 傳過來的edit_book_obj    publish_list=Publish.objects.all()   author_list=Author.objects.all()-->
  < form action="" method="post">
                 {% csrf_token %}
                 < div class="form-group">
                     < label for="">名稱</ label >
                     < input type="text" name="title" class="form-control" value="{{ edit_book_obj.title }}">
                 </ div >
 
                 < div class="form-group">
                     < label for="">價格</ label >
                     < input type="text" name="price" class="form-control" value="{{ edit_book_obj.price }}">
                 </ div >
 
                 < div class="form-group">
                     < label for="">出版日期</ label >
                     < input type="date" name="pub_date" class="form-control"
                            value="{{ edit_book_obj.publishDate|date:'Y-m-d' }}">
                 </ div >
 
                 < div class="form-group">
                     < label for="">出版社</ label >
                     < select name="publish_id" id="" class="form-control">
                         {% for publish in publish_list %}
                             {% if edit_book_obj.publish == publish %}
                                 < option selected value="{{ publish.pk }}">{{ publish.name }}</ option >
                             {% else %}
                                 < option value="{{ publish.pk }}">{{ publish.name }}</ option >
                             {% endif %}
                         {% endfor %}
                     </ select >
                 </ div >
 
                 < div class="form-group">
                     < label for="">做者</ label >
                     < select type="text" name="authors_id_list" multiple class="form-control">
                         {% for author in author_list %}
 
                         {% if author in edit_book_obj.authors.all %}
                             < option selected value="{{ author.pk }}">{{ author.name }}</ option >
                         {% else %}
                              < option value="{{ author.pk }}">{{ author.name }}</ option >
                         {% endif %}
 
                         {% endfor %}
                     </ select >
                 </ div >
                 < input type="submit" class="btn btn-default">
             </ form >

7、返回新QuerySets的API

方法名 解釋
filter() 過濾查詢對象。
exclude() 排除知足條件的對象
annotate() 使用聚合函數
order_by() 對查詢集進行排序
reverse() 反向排序
distinct() 對查詢集去重
values() 返回包含對象具體值的字典的QuerySet
values_list() 與values()相似,只是返回的是元組而不是字典。
dates() 根據日期獲取查詢集
datetimes() 根據時間獲取查詢集
none() 建立空的查詢集
all() 獲取全部的對象
union() 並集
intersection() 交集
difference() 差集
select_related() 附帶查詢關聯對象
prefetch_related() 預先查詢
extra() 附加SQL查詢
defer() 不加載指定字段
only() 只加載指定的字段
using() 選擇數據庫
select_for_update() 鎖住選擇的對象,直到事務結束。
raw() 接收一個原始的SQL查詢

8、不返回QuerySets的API

方法名 解釋
get() 獲取單個對象
create() 建立對象,無需save()
get_or_create() 查詢對象,若是沒有找到就新建對象
update_or_create() 更新對象,若是沒有找到就建立對象
bulk_create() 批量建立對象
count() 統計對象的個數
in_bulk() 根據主鍵值的列表,批量返回對象
iterator() 獲取包含對象的迭代器
latest() 獲取最近的對象
earliest() 獲取最先的對象
first() 獲取第一個對象
last() 獲取最後一個對象
aggregate() 聚合操做
exists() 判斷queryset中是否有對象
update() 批量更新對象
delete() 批量刪除對象
as_manager() 獲取管理器

9、Django 字段查詢參數及聚合函數

字段查詢是指如何指定SQL WHERE子句的內容。它們用做QuerySet的filter(), exclude()和get()方法的關鍵字參數。編程

字段名 含義 示例 等價SQL語句
exact 精確等於 Comment.objects.filter(id__exact=14) select * from Comment where id=14
iexact 大小寫不敏感的等於 Comment.objects.filter(headline__iexact=’I like this’) select * from Comment where upper(headline)=’I LIKE THIS’
contains 模糊匹配 Comment.objects.filter(headline__contains=’good’) select * from Comment where headline like 「%good%」
icontains 不區分大小寫的包含匹配    
in 包含 Comment.objects.filter(id__in=[1,5,9]) select * from Comment where id in (1,5,9)
gt 大於 Comment.objects.filter(n_visits__gt=30) select * from Comment where n_visits>30
gte 大於等於 Comment.objects.filter(n_visits__gte=30) select * from COmment where n_visits>=30
lt 小於    
lte 小於等於    
startswith 以…開頭 Comment.objects.filter(body_text__startswith=」Hello」) select * from Comment where body_text like ‘Hello%’
istartswith 不區分大小寫從開頭匹配    
endswith 以…結尾    
iendswith 不區分大小寫從結尾處匹配    
range 在…範圍內 start_date=datetime.date(2015,1,1)
end_date=datetime.date(2015.2.1)
Comment.objects.filter(
    pub_date__range=(start_date,end_date)
)
select * from Comment
where pub_date
between ‘2015-1-1’ and ‘2015-2-1’
date 日期匹配    
year Comment.objects.filter(
    pub_date__year=2015
)
select * from Comment
where pub_date
between ‘2015-1-1 0:0:0’
and ‘2015-12-31 23:59:59’
month    
day    
week 第幾周    
week_day 星期幾    
time 時間    
hour 小時    
minute 分鐘    
second    
search 1.10中被廢棄    
regex 區分大小寫的正則匹配    
iregex 不區分大小寫的正則匹配    
isnull 是否爲空 Comment.objects.filter(
    pub_date__isnull=True
)
select * from Comment where
pub_date is NULL

filter(**kwargs): 返回符合篩選條件的數據集

exclude(**kwargs):   返回不符合篩選條件的數據集

Comment.objects.filter(pub_date__year=2015)

多個filter和exclude能夠連接在一塊兒查詢

Comment.objects.filter(pub_date__year=2015).exclude(pub_date__month=1).exclude(n_visits__exact=0)

get() :查詢單條記錄,注意沒有查詢到數據的時候會報錯

Comment.objects.get(id_exact=1)

all():  查詢全部數據

Comment.objects.all()
Comment.objects.all()[:10]
Comment.objects.all[10:20]

order_by():   排序

Comment.objects.order_by('headline')
相關文章
相關標籤/搜索