目錄html
方式1:python
# 若是想單獨測試django中的某個文件,須要手動配置測試腳本(在你應用下的tests.py文件中) import os if __name__ == "__main__": os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day55.settings") import django django.setup() # 在測試腳本搭建完畢以後,才能導入django文件進行測試 from app01 import models
方式2:git
直接新建一個任意名稱的.py文件,將方式1中的配置拿過來就好了。sql
首先建立模型表:數據庫
from django.db import models # Create your models here. class Books(models.Model): title = models.CharField(max_length=32) price = models.DecimalField(max_digits=8,decimal_places=2) publish_date = models.DateField()
1.新增(create())django
向數據庫添加一條記錄後端
# 第一種 : book_obj = models.Books.objects.create(title = '人性的弱點',price='172.44',publish_date='2008-08-08') # 日期格式能夠直接寫,也能夠經過datetime模塊生成一個年月日傳進去 # 第二種:(利用對象的綁定方法) book_obj = models.Books(title = '將來簡史',price='399.44',publish_date='2008-08-09') book_obj.save() ''' 返回的是對象自己 '''
2.修改(update())app
修改表中某一條記錄的某些字段函數
res=models.Books.objects.filter(id=1).filter().filter().filter()... ''' id能夠寫成pk,表示任意一張表的主鍵字段,咱們不須要記本身建表時設置的主鍵字段的名字,直接寫成pk=? 的形式,就more你是當前表的主鍵了; 返回的res是一個QuerySet對象,能夠無限制的調用queryset對象,表示按照當前filter查詢的結果繼續按照你寫的條件繼續往下查詢; queryset對象還能夠點query查看當前結果內部對應的sql語句 ''' res=models.Books.objects.filter(id=1) print(res.query) ''' SELECT `app01_books`.`id`, `app01_books`.`title`, `app01_books`.`price`, `app01_books`.`publish_date` FROM `app01_books` WHERE `app01_books`.`id` = 1 ''' #方式1: models.Books.objects.filter(id=1).update(price=88.88) # 當條件不存在時,filter空queryset對象,推薦使用filter進行查詢。 # 方式2: book_obj = models.Books.objects.get(pk=1) # 返回的是對象自己,get在條件不存在時會報錯,不推薦使用這種方法作修改操做。 book_obj.price = 88.88 book_obj.save()
3.刪除(delete())測試
刪除表中的一條記錄
# 方式1: models.Books.objects.filter(pk=3).delete() # 方式2: book_obj = models.Books.objects.get(pk=3) book_obj.delete()
如需將你的orm查詢語句內部對應的sql語句打印在終端,能夠在Django項目的settings.py配置文件中配置以下代碼:
LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'console':{ 'level':'DEBUG', 'class':'logging.StreamHandler', }, }, 'loggers': { 'django.db.backends': { 'handlers': ['console'], 'propagate': True, 'level':'DEBUG', }, } }
all()
查詢全部
res = models.Books.objects.all() # 查詢全部 ,返回的結果QuerySet對象 ''' <QuerySet [<Books: Books object>, <Books: Books object>, <Books: Books object>, <Books: Books object>, <Books: Books object>, <Books: Books object>, <Books: Books object>, <Books: Books object>]> '''
filter()
篩選
res = models.Books.objects.filter(pk=2,title='活着') # 返回的結果QuerySet對象,支持傳多個參數 而且是and關係
get()
篩選
res = models.Books.objects.get(title='活着',price = '99.9') # 獲取的是數據對象自己,查詢條件不存在報錯,也能夠傳多個參數 ''' Books object '''
first()
取queryset中第一個數據對象 ,那麼返回的就是一個普通的數據對象了
res = models.Books.objects.filter(title='活着').first()
last()
取queryset中最後一個數據對象 ,返回的就是一個普通的數據對象
res = models.Books.objects.filter(title='活着').last()
count()
統計數據的個數,返回的是數字(數據個數)
num = models.Books.objects.count()
values()
獲取數據對象中指定的字段的值
# 按照指定條件查詢 res = models.Books.objects.filter(pk=2).values('title','price') print(res) # <QuerySet [{'title': '活着', 'price': Decimal('99.90')}]> # 查全部 res = models.Books.objects.values('title','price') # 能夠傳多個參數, 返回的是QuerySet對象,列表套字典 ''' <QuerySet [{'title': '三國演義', 'price': Decimal('99.99')}, {'title': '活着', 'price': Decimal('99.90')}, {'title': '許三多賣血記', 'price': Decimal('199.88')}, {'title': '平凡的世界', 'price': Decimal('166.66')}, {'title': '富國論', 'price': Decimal('888.88')}, {'title': '鬼谷子', 'price': Decimal('35.55')}, {'title': '人性的弱點', 'price': Decimal('172.44')}, {'title': '人性的弱點', 'price': Decimal('172.44')}]> '''
values_list()
獲取數據對象中指定的字段的值
res = models.Books.objects.values_list('title','price') # 能夠傳多個參數, 返回的是QuerySet對象,列表套元組 ''' <QuerySet [('三國演義', Decimal('99.99')), ('活着', Decimal('99.90')), ('許三多賣血記', Decimal('199.88')), ('平凡的世界', Decimal('166.66')), ('富國論', Decimal('888.88')), ('鬼谷子', Decimal('35.55')), ('人性的弱點', Decimal('172.44')), ('人性的弱點', Decimal('172.44'))]> '''
order_by()
按照指定的字段排序
# 升序(兩種寫法) res = models.Books.objects.order_by('price') # 默認是升序,返回的是queryset對象 res1 = models.Books.objects.all().order_by('price') # 降序 res = models.Books.objects.order_by('-price') # 字段前面加負號
res = models.Books.objects.order_by('price').values('title','price') print(res) # queryset對象能夠繼續經過點語法操做 ''' <QuerySet [{'title': '鬼谷子', 'price': Decimal('35.55')}, {'title': '活着', 'price': Decimal('99.90')}, {'title': '三國演義', 'price': Decimal('99.99')}, {'title': '平凡的世界', 'price': Decimal('166.66')}, {'title': '人性的弱點', 'price': Decimal('172.44')}, {'title': '人性的弱點', 'price': Decimal('172.44')}, {'title': '許三多賣血記', 'price': Decimal('199.88')}, {'title': '富國論', 'price': Decimal('888.88')}]> '''
reverse()
顛倒順序 ,必須是有序的狀況下才能顛倒
res = models.Books.objects.all().order_by('price').reverse() ''' res = models.Books.objects.reverse().values('title','price') # 不排序的狀況下返回值按照數據庫的id順序打印,沒辦法幫你顛倒 print(res) res = models.Books.objects.all().order_by('price').reverse().values('title', 'price') print(res) """ <QuerySet [{'title': '富國論', 'price': Decimal('888.88')}, {'title': '許三多賣血記', 'price': Decimal('199.88')}, {'title': '人性的弱點', 'price': Decimal('172.44')}, {'title': '人性的弱點', 'price': Decimal('172.44')}, {'title': '平凡的世界', 'price': Decimal('166.66')}, {'title': '三國演義', 'price': Decimal('99.99')}, {'title': '活着', 'price': Decimal('99.90')}, {'title': '鬼谷子', 'price': Decimal('35.55')}]> """ '''
exclude()
排除,按照指定條件排除數據,返回的是排除掉的數據以外的其餘數據
# 方式1 res = models.Books.objects.all().exclude(title='三國演義') # queryset對象 # 方式2 res = models.Books.objects.exclude(title='三國演義')
exists()
判斷查詢結果是否有值 返回結果是一個布爾值
res = models.Books.objects.filter(pk=1).exists() print(res)
distinct()
按照指定的條件去重
res = models.Books.objects.values('title','price').distinct() # 能夠傳入多個去重條件,把這多個條件都同樣的數據剔除掉 返回的是一個queryset對象
models.Tb1.objects.filter(id__lt=10, id__gt=1) # 獲取id大於1 且 小於10的值 models.Tb1.objects.filter(id__in=[11, 22, 33]) # 獲取id等於十一、2二、33的數據;,也能夠寫成括號的形式 models.Tb1.objects.exclude(id__in=[11, 22, 33]) # not in models.Tb1.objects.filter(name__contains="活") # 獲取name字段包含"活"的 models.Tb1.objects.filter(name__icontains="活") # icontains大小寫不敏感 models.Tb1.objects.filter(id__range=[1, 3]) # id範圍是1到3的,顧頭顧尾 ,也能夠寫成括號的形式 res = models.Tb1.objects.filter(title__endswith='活') # 以「活」開頭的 res = models.Tb1.objects.filter(title__endswith='活') # 以「活」結尾的 date字段: date字段能夠經過在其後加__year,__month,__day等來獲取date的特色部分數據 res=models.Tb1.objects.filter(publish_date='2008-08-08') # 指定年月日 res=models.Tb1.objects.filter(publish_date__lte='2002-03-28') # 日期小於等於2002-03-28的 也能夠是lt,或者單獨指定year,month,day res=models.Tb1.objects.filter(publish_date__gte='2002-03-28') # 日期大於等於2002-03-28的 也能夠是gt res=models.Tb1.objects.filter(publish_date__year='2007') # 只指定年份 res=models.Tb1.objects.filter(publish_date__month='08') # 指定月份 res=models.Tb1.objects.filter(publish_date__day='29') # 指定某一天 models.Tb1.objects.filter(publish_date__week_day=2) models.Tb1.objects.filter(publish_date__week_day__gte=2)
class Book(models.Model): title = models.CharField(max_length=32) price = models.DecimalField(max_digits=8,decimal_places=2) publish_date = models.DateField(auto_now_add=True) stored = models.IntegerField(default=1000) saled = models.IntegerField(default=1000) def __str__(self): # 打印對象是觸發,控制打印格式 return self.title """ auto_now:每次修改的數據的時候 都會自動更新修改書籍(展現最新的一次修改時間) auto_now_add:當數據建立出來的時候 會自動將建立時間記錄下來 """ publish = models.ForeignKey(to='Publish') # 一對多關係,外鍵字段建在查詢頻率較高的一方 authors = models.ManyToManyField(to='Author') # 多對多關係,多對多字段建在查詢頻率較高的一方 class Publish(models.Model): name = models.CharField(max_length=32) addr = models.CharField(max_length=64) def __str__(self): return self.name class Author(models.Model): name = models.CharField(max_length=32) email = models.EmailField() # 對應到數據庫的表當中是varchar類型,長度是254 author_detail = models.OneToOneField(to='AuthorDetail') # 一對一關係,一對多字段建在查詢頻率較高的一方 def __str__(self): return self.name class AuthorDetail(models.Model): phone = models.BigIntegerField() addr = models.CharField(max_length=64) def __str__(self): return self.addr ''' 模型表類建完之後,要使用數據庫遷移命令,把表遷移到數據庫當中,建表纔算完畢 python3 manage.py makemigrations python3 manage.py migrate '''
增
# 方式1: models.Book.objects.create(title='三國演義',price=222.33,publish_id=1) # 直接傳表裏面的實際字段和數據主鍵值 # 方式2: publish_obj = models.Publish.objects.filter(pk=2).first() models.Book.objects.create(title='紅樓夢',price=444.33,publish=publish_obj) # 傳虛擬字段 跟數據對象便可
改
# 方式1: models.Book.objects.filter(pk=1).update(publish_id=2) # 方式2: publish_obj = models.Publish.objects.filter(pk=1).first() models.Book.objects.filter(pk=1).update(publish=publish_obj)
刪
models.Publish.objects.filter(pk=1).delete() # 默認級聯刪除,級聯更新,這裏刪除id=1的出版社,出版社id=1的圖書也都跟着刪除
增(add)
book_obj = models.Book.objects.filter(pk=2).first() # print(book_obj.publish) # Publish object # print(book_obj.authors) # app01.Author.None 已經跨到第三張表了 # 方式1:(add支持傳入多個,以逗號分開) book_obj.authors.add(1) # 在第三張表裏面給此書籍對象綁定一個author_id=1的做者 # 方式2: author_obj1 = models.Author.objects.filter(pk=1).first() author_obj2 = models.Author.objects.filter(pk=2).first() book_obj.authors.add(author_obj1,author_obj2)
總結:add方法 可以朝第三張關係表添加數據,即支持傳數字--》add(1,2);也支持傳對象,add(author_obj,author_obj1);而且二者均可以是多個。
改(set)
book_obj = models.Book.objects.filter(pk=2).first() # 方式1: book_obj.authors.set((1,3)) book_obj.authors.set([1,]) # 方式2: author_obj = models.Author.objects.filter(pk=1).first() author_obj1 = models.Author.objects.filter(pk=2).first() book_obj.authors.set((author_obj,author_obj1))
總結:set方法修改多對多關係表中的數據,既能夠傳數字也能夠傳對象,可是傳入的一個或多個參數必須是一個可迭代對象,即用小括號或中括號括起來,內部傳入你須要的參數數量。ps: set((1,3)), set((author_obj,author_obj1))
刪(remove)
book_obj = models.Book.objects.filter(pk=2).first() # 方式1: book_obj.authors.remove(100) book_obj.authors.remove(1,2) # 方式2: author_obj = models.Author.objects.filter(pk=1).first() author_obj1 = models.Author.objects.filter(pk=2).first() book_obj.authors.remove(author_obj) book_obj.authors.remove(author_obj,author_obj1)
總結:remove方法,既能夠傳數字 也能夠傳對象;而且都支持傳多個 不須要迭代;ps:remove(1,2), remove(author_obj,author_obj1)
清空(clear)
刪除某個數據在第三張表中的全部記錄
book_obj = models.Book.objects.filter(pk=2).first() book_obj.authors.clear()
正反向查詢:
都是基於對象的跨表查詢
關係字段在誰哪 由誰查相關聯的表就是正向
若是關係字段不在當前表,就是反向
正向查詢按外鍵字段:正向查詢,當被查詢出來的數據有多個的狀況下,須要點.all();ps:app01.Author.None,一旦看到該結果 只須要加.all()便可
**反向查詢按表名小寫 + _set:**可是,在一對多,多對多的狀況下,才須要加;在一對一的關係中,不須要代表小寫加_set。
正向查詢
1.查詢書籍主鍵爲2的出版社名稱
book_obj = models.Book.objects.filter(pk=2).first() print(book_obj.publish) # 出版社對象 print(book_obj.publish.name)
2.查詢書籍主鍵爲4的做者姓名
book_obj = models.Book.objects.filter(pk=4).first() print(book_obj.authors) # app01.Author.None,跨入到了Author這張表中。 print(book_obj.authors.all()) # 一本書可能有多個做者,因此須要點.all() 返回的是queryset對象,列表內部是一個個的做者對象<QuerySet [<Author: Author object>, <Author: Author object>]>,這個是設置打印格式以後的顯示:<QuerySet [<Author: zhang>, <Author: liu>]>,表示id=4 的書籍,有兩個做者。
3.查詢做者是zhang的手機號碼
author_obj = models.Author.objects.filter(name='zhang').first() print(author_obj.author_detail) # AuthorDetail object print(author_obj.author_detail.phone)
總結:正向查詢,當被查詢出來的數據有多個的狀況下,須要點.all();
ps:app01.Author.None,一旦看到該結果 只須要加.all()便可
反向查詢
4.查詢出版社是東方出版社出版過的書籍
publish_obj = models.Publish.objects.filter(name='東方出版社').first() print(publish_obj.book_set) # app01.Book.None print(publish_obj.book_set.all())
5.查詢做者是zhang寫過的書籍
author_obj = models.Author.objects.filter(name='zhang').first() print(author_obj.book_set) # app01.Book.None print(author_obj.book_set.all()) # app01.Book.None
6.查詢手機號是120的做者姓名
author_detail_obj = models.AuthorDetail.objects.filter(phone=120).first() print(author_detail_obj.author) # Author object 不需類名小寫+_set,直接做者詳情對象點類名(Author)小寫便可 print(author_detail_obj.author.email) # 120qq.com
基於雙下滑線的聯表查詢操做,能讓兩張表組成一張表,使用一條django的orm語句就能查詢出想要的信息,使操做更加簡潔化。
1.查詢書籍pk爲2的出版社名稱
# 方式1:正向查詢 res = models.Book.objects.filter(pk=2).values('publish__name') print(res) # <QuerySet [{'publish__name': '東方出版社'}]> # 方式2:反向查詢 res = models.Publish.objects.filter(book__pk=2).values('name') print(res) # <QuerySet [{'name': '北方出版社'}]>
2.查詢書籍pk爲2的做者姓名和郵箱
# 方式1:正向查詢 res =models.Book.objects.filter(pk=2).values('authors__name','authors__email') print(res) # <QuerySet [{'authors__name': 'zhang', 'authors__email': '110@qq.com'}, {'authors__name': 'liu', 'authors__email': '120qq.com'}]> 不須要像上面基本方法的跨表查詢,這裏不須要用點.all() # 方式2:反向查詢 res =models.Author.objects.filter(book__pk=2).values('name','email') print(res) # <QuerySet [{'name': 'zhang', 'email': '110@qq.com'}, {'name': 'liu', 'email': '120qq.com'}]>
總結: models後面點的誰 就以誰爲基表
3.查詢做者是zhang的家庭地址
# 方式1:正向查詢 res=models.Author.objects.filter(name='egon').values('author_detail__addr') print(res) # 方式2:反向查詢 res=models.AuthorDetail.objects.filter(author__name='liu').values('addr') print(res)
4.查詢出版社是東方出版社出版過的書的名字
# 方式1:正向查詢 res = models.Publish.objects.filter(name='東方出版社').values('book__title') print(res) # 方式2:反向查詢 res = models.Book.objects.filter(publish__name='東方出版社').values('title') print(res)
5.查詢書籍pk是2的做者的手機號
# 方式1:正向查詢 res=models.Book.objects.filter(pk=2).values('authors__author_detail__phone') print(res) # 方式2:反向查詢 res=models.Author.objects.filter(book__pk=2).values('author_detail__phone') print(res)
1.關鍵字 aggregate
2.還須要導入模塊
from django.db.models import Max, Min, Sum, Avg, Count
from django.db.models import Max, Min, Sum, Count, Avg # 1.篩選出價格最高的書籍的 res = models.Book.objects.aggregate(mr = Max('price')) print(res) # {'mr': Decimal('222.99')} # 2.求書籍總價格 res = models.Book.objects.aggregate(sm = Sum('price')) print(res) # {'sm': Decimal('600.58')} # 3.求書籍平均價格 res = models.Book.objects.aggregate(av = Avg('price')) print(res) # {'av': 150.145} # 4.一塊兒使用 res=models.Book.objects.aggregate(Max('price'),Min('price'),Sum('price'),Count('price'),Avg('price')) print(res) ''' {'price__max': Decimal('222.99'), 'price__min': Decimal('88.80'), 'price__sum': Decimal('600.58'), 'price__count': 4, 'price__avg': 150.145} '''
1.關鍵字 annotate
2.藉助於聚合函數
from django.db.models import Max, Min, Sum, Avg, Count
1).分組查詢annotate()至關於sql語句中的group by,是在分組後,對每一個組進行單獨的聚合,須要強調的是,在進行單表查詢時,annotate()必須搭配values()使用:values("分組字段").annotate(聚合函數)
每一個部門下的員工數 res=Employee.objects.values('department').annotate(num=Count('id')) # 至關於sql: # select department,count(id) as num from app01_employee group by department; print(res) # 輸出:<QuerySet [{'department': '財務部', 'num': 2}, {'department': '技術部', 'num': 3}, {'department': '運營部', 'num': 2}]>
2).跟在annotate前的values方法,是用來指定分組字段,即group by後的字段,而跟在annotate後的values方法,則是用來指定分組後要查詢的字段,即select 後跟的字段
res=Employee.objects.values('department').annotate(num=Count('id')).values('num') # 至關於sql: # select count(id) as num from app01_employee group by department; print(res) # 輸出:<QuerySet [{'num': 2}, {'num': 3}, {'num': 2}]>
3).跟在annotate前的filter方法表示where條件,跟在annotate後的filter方法表示having條件,以下:
# 查詢男員工數超過2人的部門名 res=Employee.objects.filter(gender=1).values('department').annotate(male_count=Count("id")).filter(male_count__gt=2).values('department') print(res) # 輸出:<QuerySet [{'department': '技術部'}]> # 解析: # 一、跟在annotate前的filter(gender=1) 至關於 where gender = 1,先過濾出全部男員工信息 # 二、values('department').annotate(male_count=Count("id")) 至關於group by department,對過濾出的男員工按照部門分組,而後聚合出每一個部門內的男員工數賦值給字段male_count # 三、跟在annotate後的filter(male_count__gt=2) 至關於 having male_count > 2,會過濾出男員工數超過2人的部門 # 四、最後的values('department')表明從最終的結果中只取部門名
總結:
一、values()在annotate()前表示group by的字段,在後表示取值 一、filter()在annotate()前表示where條件,在後表示having
須要注意的是,若是咱們在annotate前沒有指定values(),那默認用表中的id字段做爲分組依據,而id各不相同,如此分組是沒有意義的。
1.統計每一本書的做者個數 書名 和對應的做者人數
res=models.Book.objects.annotate(author_num=Count('authors__id')).values('title','author_num') print(res)
2.統計出每一個出版社賣的最便宜的書的價格 出版社的名字 價格
res=models.Publish.objects.annotate(min_price=Min('book__price')).values('name','min_price') print(res)
3.統計不止一個做者的圖書
res=models.Book.objects.annotate(author_num=Count('authors')).filter(author_num__gt=1).values('title','author_num') print(res)
4.查詢各個做者出的書的總價格 做者名字 總價格
res=models.Author.objects.annotate(sum_price=Sum('book__price')).values('name','sum_price') print(res)
F查詢
可以幫你拿到表中字段所對應的數據
eg:查詢賣出數大於庫存數的書籍
from django.db.models import F,Q res = models.Book.objects.filter(kun_cun__gt = F('mai_cun')).values('title') # 後面的條件是來自於數據庫的其餘字段值 print(res) # <QuerySet [{'title': '天龍八部'}]>
2.將全部書的價格上漲100塊
models.Book.objects.all().update(price=F('price') + 100)
3.將全部書的名稱後面所有加上 "爆款" 後綴
from django.db.models.functions import Concat from django.db.models import Value ret3 = models.Book.objects.update(title=Concat(F('title'), Value('新款')))
Q查詢
filter只能按照and的關係查詢數據,而Q查詢可以支持修改多個查詢條件的關係(and or not)
1.查詢一下書籍名稱是三國演義 或者 庫存數是500的書籍
from django.db.models import Q res = models.Book.objects.filter(title='三國演義',kun_cun=500) # and關係 res = models.Book.objects.filter(title='三國演義',kun_cun=500) # and關係 res = models.Book.objects.filter(Q(title='三國演義'),Q(kun_cun=500))# Q包裹以後逗號仍是and關係 res = models.Book.objects.filter(Q(title='三國演義') | Q(kun_cun=500)) # |就是or的關係 res = models.Book.objects.filter(~Q(title='三國演義')|Q(kun_cun=500)) # ~就是not關係 print(res)
Q對象高級用法
q = Q() q.connector = 'or' # 默認是and 能夠改爲or q.children.append(('title','三國演義')) q.children.append(('kun_cun__gt',500)) res = models.Book.objects.filter(~q) # 取反 print(res) from django.db import transaction with transaction.atomic(): # 在縮進的代碼中書寫數據庫操做 # 該縮進內的全部代碼 都是一個事務 pass
orm字段及參數 CharField varchar IntegerField int BigIntegerField bigint EmailField varchar(254) DateField DateTimeField auto_now:每次修改數據的時候 都會自動將當前修改時間更新上去 實時更新 auto_now_add:在建立數據的時候 會將當前時間自動記錄 以後不會自動修改 除非你人爲修改 AutoField auto_increment BooleanField 布爾值 該字段在存儲的時候 你只須要傳佈爾值True或False 它會自動存成1/0 TextField 專門用來存大段文本 FileField 專門用來文件路徑 '/etc/data/a.txt' upload_to = '/etc/data' 給該字段傳值的時候 直接傳文件對象 會自動將文件對象保存到upload_to後面指定的文件路徑中 而後將路徑保存到數據庫 DecimalField(Field) - 10進制小數 - 參數: max_digits,小數總長度 decimal_places,小數位長度
from django.db import models # Create your models here. #Django中沒有對應的char類型字段,可是咱們能夠本身建立 class FixCharField(models.Field): ''' 自定義的char類型的字段類 ''' def __init__(self,max_length,*args,**kwargs): self.max_length=max_length # # 從新調用父類的方法 super().__init__(max_length=max_length,*args,**kwargs) def db_type(self, connection): ''' 限定生成的數據庫表字段類型char,長度爲max_length指定的值 :param connection: :return: ''' return 'char(%s)'%self.max_length #應用上面自定義的char類型 class Class(models.Model): id=models.AutoField(primary_key=True) title=models.CharField(max_length=32) class_name=FixCharField(max_length=16) gender_choice=((1,'男'),(2,'女'),(3,'保密')) gender=models.SmallIntegerField(choices=gender_choice,default=3)