Django模型層—單表操做

單表操做

一,建立表

1,建立模型python

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

from django.db import models

# Create your models here.
class Book(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=64)
    pub_data = models.DateField()
    price = models.DecimalField(max_digits=5, decimal_places=2)
    publish = models.CharField(max_length=12)
    def __str__(self):
        return self.name

2,更多字段參數git

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

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)
        - 二進制類型

字段
字段
(1)null
 
若是爲True,Django 將用NULL 來在數據庫中存儲空值。 默認值是 False.
 
(1)blank
 
若是爲True,該字段容許不填。默認爲False。
要注意,這與 null 不一樣。null純粹是數據庫範疇的,而 blank 是數據驗證範疇的。
若是一個字段的blank=True,表單的驗證將容許該字段是空值。若是字段的blank=False,該字段就是必填的。
 
(2)default
 
字段的默認值。能夠是一個值或者可調用對象。若是可調用 ,每有新對象被建立它都會被調用。
 
(3)primary_key
 
若是爲True,那麼這個字段就是模型的主鍵。若是你沒有指定任何一個字段的primary_key=True,
Django 就會自動添加一個IntegerField字段作爲主鍵,因此除非你想覆蓋默認的主鍵行爲,
不然不必設置任何一個字段的primary_key=True。
 
(4)unique
 
若是該值設置爲 True, 這個數據字段的值在整張表中必須是惟一的
 
(5)choices
由二元組組成的一個可迭代對象(例如,列表或元組),用來給字段提供選擇項。 若是設置了choices ,默認的表單將是一個選擇框而不是標準的文本框,<br>並且這個選擇框的選項就是choices 中的選項。

參數
參數
class UserInfo(models.Model):
        nid = models.AutoField(primary_key=True)
        username = models.CharField(max_length=32)
        class Meta:
            # 數據庫中生成的表名稱 默認 app名稱 + 下劃線 + 類名
            db_table = "table_name"

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

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

            # admin中顯示的表名稱
            verbose_name

            # verbose_name加s
            verbose_name_plural

元信息
元信息

3,sitiing配置數據庫

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

DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'lqz', 'USER': 'root', 'PASSWORD': '123456', 'HOST': '127.0.0.1', 'PORT': 3306, 'ATOMIC_REQUEST': True, 'OPTIONS': { "init_command": "SET storage_engine=MyISAM", } } } ''' 'NAME':要鏈接的數據庫,鏈接前須要建立好 'USER':鏈接數據庫的用戶名 'PASSWORD':鏈接數據庫的密碼 'HOST':鏈接主機,默認本機 'PORT':端口 默認3306 'ATOMIC_REQUEST': True, 設置爲True統一個http請求對應的全部sql都放在一個事務中執行(要麼全部都成功,要麼全部都失敗)。 是全局性的配置, 若是要對某個http請求放水(而後自定義事務),能夠用non_atomic_requests修飾器 'OPTIONS': { "init_command": "SET storage_engine=MyISAM", } 設置建立表的存儲引擎爲MyISAM,INNODB '''

注意1:NAME即數據庫的名字,在mysql鏈接前該數據庫必須已經建立,而上面的sqlite數據庫下的db.sqlite3則是項目自動建立 USER和PASSWORD分別是數據庫的用戶名和密碼。設置完後,再啓動咱們的Django項目前,咱們須要激活咱們的mysql。而後,啓動項目,會報錯:no module named MySQLdb 。這是由於django默認你導入的驅動是MySQLdb,但是MySQLdb 對於py3有很大問題,因此咱們須要的驅動是PyMySQL 因此,咱們只須要找到項目名文件下的__init__,在裏面寫入:session

import pymysql
pymysql.install_as_MySQLdb()

最後經過兩條數據庫遷移命令便可在指定的數據庫中建立表 :app

python manage.py makemigrations
python manage.py migrate

注意2:確保配置文件中的INSTALLED_APPS中寫入咱們建立的app名稱ide

複製代碼
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    "book"
]
複製代碼

注意3: 若是想打印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',
        },
    }
}
複製代碼

4,增長,刪除字段

  刪除,直接註釋掉字段,執行數據庫遷移命令便可

  新增字段,在類裏直接新增字段,直接執行數據庫遷移命令會提示輸入默認值,此時須要設置

注意:

  1 數據庫遷移記錄都在 app01下的migrations裏

  2 使用showmigrations命令能夠查看沒有執行migrate的文件

  3  makemigrations是生成一個文件,migrate是將更改提交到數據量

 添加表記錄

方式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()

查詢記錄

查詢API

 

<1> all():                  查詢全部結果
  
<2> filter(**kwargs):       它包含了與所給篩選條件相匹配的對象
  
<3> get(**kwargs):          返回與所給篩選條件相匹配的對象,返回結果有且只有一個,若是符合篩選條件的對象超過一個或者沒有都會拋出錯誤。
  
<4> exclude(**kwargs):      它包含了與所給篩選條件不匹配的對象
 
<5> order_by(*field):       對查詢結果排序('-id')
  
<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():            從返回結果中剔除重複紀錄
def index(request):
    # 添加表記錄++++++++++++++++++++++++++++++++++
    # 方式一
    # book=Book(name='紅樓夢',pub_data='2015-10-12',price=88,publish='老男孩出版社')
    # book.save()
    # 方式二
    # Book.objects.create(name='Python紅寶書',pub_data='2010-10-12',price=100,publish='人民出版社')
    # 查詢表記錄++++++++++++++++++++++++++++++++++
    # QUerySet數據類型(相似於一個列表,裏面放着一些對象)
    # 1 方法的返回值是什麼
    # 2 方法的調用者
    # (1) all方法 返回一個QuerySet對象
    # book_list=Book.objects.all()
    # print(book_list[1].name)
    # print(book_list)
    # for obj in book_list:
    #     print(obj.name)
    # (2)first last:調用者是queryset對象,返回值是對象
    # book=Book.objects.all().first()
    # book2=Book.objects.all().last()
    # print(book)
    # print(book2)
    # (3) filter  返回值是queryset對象(至關於where語句)
    # 能夠加多個過濾條件
    # book=Book.objects.filter(name='紅樓夢').first()
    # print(book)
    # (4)get方法 有且只有一個查詢結果纔有意義 返回值是一個對象
    # book=Book.objects.get(name='紅樓夢')
    # print(book)
    # 直接報錯
    # book = Book.objects.get(name='紅樓夢eee')
    # --------------最經常使用-----------------
    # (5)exclude 除了查詢以外的 返回值也是queryset
    # ret=Book.objects.exclude(name='紅樓夢')
    # print(ret)
    # (6)order_by(默認升序,加個- 就是降序),能夠多個過濾條件調用者是queryset返回值也是queryset
    # book_list=Book.objects.all().order_by('id')
    # book_list=Book.objects.all().order_by('-id','price')
    # print(book_list)
    # (7)count() 調用者是queryset,返回值是int
    # ret=Book.objects.all().count()
    # print(ret)
    # (8)exist()判斷是是否有值,不能傳參數,
    # ret=Book.objects.all().exists()
    # print(ret)
    # (9)values方法
    # 查詢全部書籍的名稱(裏面傳的值,前提是表有這個字段)也是queryset可是裏面放的是字典
    '''
    values原理
    temp=[]
    for obj in Book.objects.all():
        temp.append({'name':obj.name})
    '''
    # ret=Book.objects.all().values('name')
    # print(ret)
    # 不加.all()也能夠,調用是queryset返回值也是queryset
    # ret=Book.objects.values('price')
    # print(ret)
    # (10)value_list
    # ret=Book.objects.all().values_list('price','name')
    # print(ret)
    # (11) distinct  seletc * 的時候沒有意義
    # SELECT DISTINCT name from app01_book;
    # 沒有任何意義,不要這樣麼用
    # Book.objects.all().distinct()
    # ret=Book.objects.all().values('name').distinct()
    # print(ret)

    # 雙下劃線模糊查詢-----------------------
    # 查詢價格大於100的書
    # ret=Book.objects.filter(price__gt=100)
    # print(ret)
    # 查詢大於50小於100的書
    # ret=Book.objects.filter(price__gt=50,price__lt=100)
    # print(ret)
    # 查詢已紅樓開頭的書
    # ret=Book.objects.filter(name__startswith='紅樓')
    # print(ret)
    # 查詢包含‘紅’的書
    # ret= Book.objects.filter(name__contains='紅')
    # print(ret)
    # icontains  不區分大小寫
    # 價格在50,88,100 中的
    # ret=Book.objects.filter(price__in=[50,88,100])
    # print(ret)
    # 出版日期在2018年的
    # ret=Book.objects.filter(pub_data__year=2015,pub_data__month=2)
    # print(ret)
    # 刪除,修改------------------------
    # delete:調用者能夠是queryset也能夠是model對象
    # 刪除價格爲188的書有返回值 (1, {'app01.Book': 1}) 刪除的個數,那張表,記錄數
    # ret=Book.objects.filter(price=188).delete()
    # print(ret)
    # ret=Book.objects.filter(price=100).first().delete()
    # print(ret)

    # 修改 update只能queryset來調用 返回值爲int
    # ret=Book.objects.filter(name='紅樓夢1').update(name='紅樓夢')
    # print(ret)
    # 報錯
    # Book.objects.filter(name='紅樓夢').first().update(name='紅樓夢1')

    # ret=Book.objects.filter(name='紅樓夢1').first()
    # print(ret.delete())
    # aa=Publish.objects.filter(name='人民出版社')
    # print(type(aa))
    # aa.delete()

    return HttpResponse('ok')

測試數據
測試例

基於雙下劃線模糊查詢

Book.objects.filter(price__in=[100,200,300])
Book.objects.filter(price__gt=100)
Book.objects.filter(price__lt=100)
Book.objects.filter(price__gte=100)
Book.objects.filter(price__lte=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)

刪除表記錄

刪除方法就是 delete()。它運行時當即刪除對象而不返回任何值。例如:

model_obj.delete()

你也能夠一次性刪除多個對象。每一個 QuerySet 都有一個 delete() 方法,它一次性刪除 QuerySet 中全部的對象。

例如,下面的代碼將刪除 pub_date 是2005年的 Entry 對象:

Entry.objects.filter(pub_date__year=2005).delete()

在 Django 刪除對象時,會模仿 SQL 約束 ON DELETE CASCADE 的行爲,換句話說,刪除一個對象時也會刪除與它相關聯的外鍵對象。例如:

b = Blog.objects.get(pk=1)
# This will delete the Blog and all of its Entry objects.
b.delete()

要注意的是: delete() 方法是 QuerySet 上的方法,但並不適用於 Manager 自己。這是一種保護機制,是爲了不意外地調用 Entry.objects.delete() 方法致使 全部的 記錄被誤刪除。若是你確認要刪除全部的對象,那麼你必須顯式地調用:

Entry.objects.all().delete() 

若是不想級聯刪除,能夠設置爲:

pubHouse = models.ForeignKey(to='Publisher', on_delete=models.SET_NULL, blank=True, null=True)

修改表記錄

Book.objects.filter(title__startswith="py").update(price=120

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

相關文章
相關標籤/搜索