1. 一對一(水平分表)
母表: UserInfo id name age 子表: private id salary sp建立模型語句:python
class UserInfo(models.Model): name = models.CharField(max_length=32, null=True) age = models.IntegerField(null=True) class Private(models.Model): salary = models.CharField(max_length=32, null=True) sp = models.OneToOneField("UserInfo", null=True) # OneToOneField 一對一建立數據:mysql
models.UserInfo.objects.create(name="潘立府",age="18") # 注意字段sp_id纔是Private表的真實字段。sp則是一個對象 models.Private.objects.create(salary='50000',sp_id='1')需求:從母表中查詢子表中的數據(查詢一下name='xxxx'的salary)sql
res = models.UserInfo.objects.filter(name='plf').first() # 語法: res.子表表名小寫.子表字段名 print(res.private.salary)需求:從子表中查詢母表中的數據(查詢一下salary=xxxx的姓名和年齡)數據庫
# 從子表查詢母表中的數據 res = models.Private.objects.filter(salary=5000).first() # 語法: 對象.關聯的字段.母表的字段 print(res.sp.name,res.sp.age)2. 多對多
相親的模型 Boy: id name Girl: id name 1 真真 2 連連 3 愛愛 4 鳳姐 5 喬碧蘿 boy2girl(bid和gid應該是聯合惟一) id bid gid 1 1 1 2 1 2 3 1 3 4 2 2 5 2 4 6 2 5建表語句:django
# 第一種建立方式 """ class Boy(models.Model): bname = models.CharField(max_length=32,null=True) class Girl(models.Model): gname = models.CharField(max_length=32,null=True) class Boy2Girl(models.Model): b = models.ForeignKey("Boy",null=True) g = models.ForeignKey("Girl",null=True) # 聯合惟一索引 class Meta: unique_together = [ ('b','g') ] # 聯合索引 #class Meta: # index_together = [ # ('b','g') # ] """ # 第二種建立方式 """ class UserInfo(models.Model): name = models.CharField(max_length=32, null=True) age = models.IntegerField(null=True) class Private(models.Model): salary = models.CharField(max_length=32, null=True) sp = models.OneToOneField("UserInfo", null=True) class Boy(models.Model): bname = models.CharField(max_length=32,null=True) g = models.ManyToManyField('Girl',null=True) class Girl(models.Model): gname = models.CharField(max_length=32,null=True) """ # 兩種方式的區別 ''' 第一種方式比較的靈活,本身能夠添加任意的字段 第二種方式比較死板,只能生成兩個字段。若是未來業務擴展,就須要從新打破重來 所以,推薦使用第一種方式。 '''建立數據:app
boyinfo = [ models.Boy(bname='雷俊'), models.Boy(bname='雷鳴'), models.Boy(bname='雷震子'), models.Boy(bname='雷鋒'), models.Boy(bname='雷軍'), ] models.Boy.objects.bulk_create(boyinfo) girlinfo = [ models.Girl(gname="真真"), models.Girl(gname="練練"), models.Girl(gname="愛愛"), models.Girl(gname="鳳姐"), models.Girl(gname="喬碧蘿"), ] models.Girl.objects.bulk_create(girlinfo) b2ginfo = [ models.Boy2Girl(b_id=1,g_id=1), models.Boy2Girl(b_id=1,g_id=2), models.Boy2Girl(b_id=1,g_id=3), models.Boy2Girl(b_id=2,g_id=4), models.Boy2Girl(b_id=2,g_id=5), models.Boy2Girl(b_id=1,g_id=5), ] models.Boy2Girl.objects.bulk_create(b2ginfo) # 另類的建立數據的方式 bobj = models.Boy.objects.filter(bname='雷俊').first() gobj = models.Boy.objects.filter(bname='喬碧蘿').first() # 第一種 models.Boy2Girl.objects.create(b=bobj,g=gobj) # 第二種 models.Boy2Girl.objects.create(b_id=bobj.id,g_id=gobj.id)需求:查找一下和雷俊約會的姑娘url
# 第一種方式:從Boy表中開始查詢 res = models.Boy.objects.filter(bname='雷俊').first() # res 是一個對象: Boy object res = res.boy2girl_set.all() for i in res: # i對象是 Boy2Girl 的對象 # i.g 是一個對象。而後直接使用.獲取gname print(i.g.gname) print(res) # 第二種方式:從Boy2Girl表開始查詢 res = models.Boy2Girl.objects.filter(b__bname='雷俊').all() print(res) for love in res: print(love.g.gname) # 第三種方式:在第二種方式的基礎上進行改進 res = models.Boy2Girl.objects.filter(b__bname='雷俊').values('g__gname') print(res) ''' <QuerySet [{'g__gname': '真真'}, {'g__gname': '練練'}, {'g__gname': '愛愛'}, {'g__gname': '喬碧蘿'}]> ''' # 第四種方式: res = models.Boy.objects.filter(bname='雷俊').values('boy2girl__g__gname') print(res)
數字類型(重點)spa
mysql orm tinyint 不存在 smallint SmallIntegerField mediumint 不存在 int(unsigned) IntegerField(PositiveIntegerField) bigint(unsigned) BigIntegerField(PositiveBigIntegerField) decimal DecimalField float FloatField double 不存在 字符串code
mysql orm char 不存在 varchar CharField text TextField 時間
mysql orm date DateField datetime DateTimeField orm中數據類型:
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 上傳圖片的寬度保存的數據庫字段名(字符串)
參數
mysql約束
null 數據庫中字段是否能夠爲空 db_column 數據庫中字段的列名 default 數據庫中字段的默認值 primary_key 數據庫中字段是否爲主鍵 db_index 數據庫中字段是否能夠創建索引 unique 數據庫中字段是否能夠創建惟一索引 unique_for_date 數據庫中字段【日期】部分是否能夠創建惟一索引 unique_for_month 數據庫中字段【月】部分是否能夠創建惟一索引 unique_for_year 數據庫中字段【年】部分是否能夠創建惟一索引orm約束
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'), ] )
一:django內置分頁
urls.py
urlpatterns = [ url(r'^test2/', views.test2), ]views.py
def test2(request): cur_page = request.GET.get('cur_page') print(cur_page,type(cur_page)) cur_page = int(cur_page) userlist = models.UserInfo.objects.all() from django.core.paginator import Paginator paginator = Paginator(userlist,10) users = paginator.page(cur_page) return render(request,'index.html',{'users':users}) # paginator擁有的屬性 # per_page :每頁顯示的條目的數量 # count :數據總個數 # num_pages :總頁數 # page_range:總頁數的索引範圍 如:(1,10),(1,200) # page :page對象 # users擁有的屬性 # has_next 是否有下一頁 # next_page_number 下一頁頁碼 # has_previous 是否有上一頁 # previous_page_number 上一頁頁碼 # object_list 分頁以後的數據列表 # number 當前頁 # paginator paginator對象index.html
<html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <ul> {% for foo in users.object_list %} <li>{{ foo.name }}</li> {% endfor %} {% if users.has_previous %} <a href="/test2/?cur_page={{ users.previous_page_number }}">上一頁</a> {% endif %} {% for num in users.paginator.page_range %} <a href="/test2/?cur_page={{ num }}">{{ num }}</a> {% endfor %} {% if users.has_next %} <a href="/test2/?cur_page={{ users.next_page_number }}">下一頁</a> {% endif %} </ul> </body> </html>二:自定義分頁
urls.py
urlpatterns = [ url(r'^test3/', views.test3), ]views.py
class PageInfo(): def __init__(self,cur_page,total,per_page=10,show_page=11): self.cur_page = cur_page # 當前頁 self.per_page = per_page # 一頁顯示多少行數據 self.total = total # 總數據有多少行 self.show_page = show_page # 頁面顯示多少索引 a,b = divmod(self.total,self.per_page) if b: a = a + 1 self.total_page = a # 總頁數 def get_start(self): start = (self.cur_page - 1) * self.per_page return start def get_end(self): return self.cur_page * self.per_page def get_page(self): half = (self.show_page - 1) // 2 #### taotal_page = 5 < show_page = 11 if self.total_page < self.show_page: begin = 1 end = self.total_page else: #### 左邊極值判斷 if self.cur_page - half <= 0: begin = 1 # end = self.cur_page + half end = self.show_page #### 右邊極值的判斷 elif self.cur_page + half > self.total_page: # begin = self.cur_page - half begin = self.total_page - self.show_page + 1 end = self.total_page ### 31 #### 正常頁碼判斷 else: begin = self.cur_page - half end = self.cur_page + half page_list = [] if self.cur_page == 1: astr = "<li><a href='#' aria-label='Previous'><span aria-hidden='true'>«</span></a></li>" else: astr = "<li><a href='/test3/?cur_page=%s' aria-label='Previous'><span aria-hidden='true'>«</span></a></li>" % ( self.cur_page - 1) page_list.append(astr) for i in range(begin, end + 1): if self.cur_page == i: # astr = "<a style='display:inline-block; padding:5px;margin:5px;background-color:red;' href='/custom/?cur_page=%s'>%s</a>" % (i, i) astr = "<li class='active'><a href='/test3/?cur_page=%s'>%s</a></li>" % (i, i) else: # astr = "<a style='display:inline-block; padding:5px;margin:5px' href='/custom/?cur_page=%s'>%s</a>" % (i, i) astr = "<li><a href='/test3/?cur_page=%s'>%s</a></li>" % (i, i) page_list.append(astr) if self.cur_page == self.total_page: astr = "<li><a href='#' aria-label='Next'><span aria-hidden='true'>»</span></a></li>" else: astr = "<li><a href='/test3/?cur_page=%s' aria-label='Next'><span aria-hidden='true'>»</span></a></li>" % ( self.cur_page + 1) page_list.append(astr) s = " ".join(page_list) return s def test3(request): # mysql中limit的分頁公式 ''' cur_page: 當前頁 show_page_num: 顯示多少頁 start_page: 起始頁 limit 起始位置a, 顯示多少頁b a = ( cur_page - 1 ) * show_page_num b = show_page_num ''' # 在django中的分頁公式(models.UserInfo.objects.filter(id__lte=44)[start:end]) """ show_page_num = 10 cur_page = 1 start = 0 end = 10 cur_page = 2 start = 10 end = 20 cur_page = 3 start =20 end = 30 start = (cur_page - 1) * show_page_num end = cur_page * show_page_num """ cur_page = request.GET.get("cur_page") cur_page = int(cur_page) total = models.UserInfo.objects.count() obj = PageInfo(cur_page,total) start = obj.get_start() end = obj.get_end() # 獲取總數據 user_list = models.UserInfo.objects.all()[start:end] return render(request,'custom.html',{"user_list":user_list,"page":obj})custom.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <ul> {% for foo in users.object_list %} <li>{{ foo.name }}</li> {% endfor %} {% if users.has_previous %} <a href="/test2/?cur_page={{ users.previous_page_number }}">上一頁</a> {% endif %} {% for num in users.paginator.page_range %} <a href="/test2/?cur_page={{ num }}">{{ num }}</a> {% endfor %} {% if users.has_next %} <a href="/test2/?cur_page={{ users.next_page_number }}">下一頁</a> {% endif %} </ul> </body> </html>