數據庫的三大設計範式html
urls.py前端
models.pyvue
views.pypython
home.htmllinux
book_list.htmlgit
book_edit.htmlgithub
book_add.htmlajax
1 """ 2 用戶表 3 性別 4 學歷 5 工做經驗 6 是否結婚 7 是否生子 8 客戶來源 9 ... 10 針對某個能夠列舉徹底的可能性字段,咱們應該如何存儲 11 12 只要某個字段的可能性是能夠列舉徹底的,那麼通常狀況下都會採用choices參數 13 """ 14 class User(models.Model): 15 username = models.CharField(max_length=32) 16 age = models.IntegerField() 17 # 性別 18 gender_choices = ( 19 (1,'男'), 20 (2,'女'), 21 (3,'其餘'), 22 ) 23 gender = models.IntegerField(choices=gender_choices) 24 25 score_choices = ( 26 ('A','優秀'), 27 ('B','良好'), 28 ('C','及格'), 29 ('D','不合格'), 30 ) 31 # 保證字段類型跟列舉出來的元祖第一個數據類型一致便可 32 score = models.CharField(choices=score_choices,null=True) 33 """ 34 該gender字段存的仍是數字 可是若是存的數字在上面元祖列舉的範圍以內 35 那麼能夠很是輕鬆的獲取到數字對應的真正的內容 36 37 1.gender字段存的數字不在上述元祖列舉的範圍內容 38 2.若是在 如何獲取對應的中文信息 39 """ 40 41 42 from app01 import models 43 # models.User.objects.create(username='jason',age=18,gender=1) 44 # models.User.objects.create(username='egon',age=85,gender=2) 45 # models.User.objects.create(username='tank',age=40,gender=3) 46 # 存的時候 沒有列舉出來的數字也能存(範圍仍是按照字段類型決定) 47 # models.User.objects.create(username='tony',age=45,gender=4) 48 49 # 取 50 # user_obj = models.User.objects.filter(pk=1).first() 51 # print(user_obj.gender) 52 # 只要是choices參數的字段 若是你想要獲取對應信息 固定寫法 get_字段名_display() 53 # print(user_obj.get_gender_display()) 54 55 user_obj = models.User.objects.filter(pk=4).first() 56 # 若是沒有對應關係 那麼字段是什麼仍是展現什麼 57 print(user_obj.get_gender_display()) # 4
1 class School(models.Model): 2 """ 3 校區表 4 如: 5 北京沙河校區 6 上海校區 7 8 """ 9 title = models.CharField(verbose_name='校區名稱', max_length=32) 10 11 def __str__(self): 12 return self.title 13 14 class Course(models.Model): 15 """ 16 課程表 17 如: 18 Linux基礎 19 Linux架構師 20 Python自動化開發精英班 21 Python自動化開發架構師班 22 Python基礎班 23 go基礎班 24 """ 25 name = models.CharField(verbose_name='課程名稱', max_length=32) 26 27 def __str__(self): 28 return self.name 29 30 class Department(models.Model): 31 """ 32 部門表 33 市場部 1000 34 銷售 1001 35 36 """ 37 title = models.CharField(verbose_name='部門名稱', max_length=16) 38 code = models.IntegerField(verbose_name='部門編號', unique=True, null=False) 39 40 def __str__(self): 41 return self.title 42 43 class UserInfo(models.Model): 44 """ 45 員工表 46 """ 47 48 name = models.CharField(verbose_name='員工姓名', max_length=16) 49 email = models.EmailField(verbose_name='郵箱', max_length=64) 50 depart = models.ForeignKey(verbose_name='部門', to="Department",to_field="code") 51 user=models.OneToOneField("User",default=1) 52 def __str__(self): 53 return self.name 54 55 class ClassList(models.Model): 56 """ 57 班級表 58 如: 59 Python全棧 面授班 5期 10000 2017-11-11 2018-5-11 60 """ 61 school = models.ForeignKey(verbose_name='校區', to='School') 62 course = models.ForeignKey(verbose_name='課程名稱', to='Course') 63 semester = models.IntegerField(verbose_name="班級(期)") 64 65 66 price = models.IntegerField(verbose_name="學費") 67 start_date = models.DateField(verbose_name="開班日期") 68 graduate_date = models.DateField(verbose_name="結業日期", null=True, blank=True) 69 memo = models.CharField(verbose_name='說明', max_length=256, blank=True, null=True, ) 70 71 teachers = models.ManyToManyField(verbose_name='任課老師', to='UserInfo',limit_choices_to={'depart':1002}) 72 tutor = models.ForeignKey(verbose_name='班主任', to='UserInfo',related_name="class_list",limit_choices_to={'depart':1006}) 73 74 75 def __str__(self): 76 return "{0}({1}期)".format(self.course.name, self.semester) 77 78 79 class Customer(models.Model): 80 """ 81 客戶表 82 """ 83 qq = models.CharField(verbose_name='qq', max_length=64, unique=True, help_text='QQ號必須惟一') 84 85 name = models.CharField(verbose_name='學生姓名', max_length=16) 86 gender_choices = ((1, '男'), (2, '女')) 87 gender = models.SmallIntegerField(verbose_name='性別', choices=gender_choices) 88 89 education_choices = ( 90 (1, '重點大學'), 91 (2, '普通本科'), 92 (3, '獨立院校'), 93 (4, '民辦本科'), 94 (5, '大專'), 95 (6, '民辦專科'), 96 (7, '高中'), 97 (8, '其餘') 98 ) 99 education = models.IntegerField(verbose_name='學歷', choices=education_choices, blank=True, null=True, ) 100 graduation_school = models.CharField(verbose_name='畢業學校', max_length=64, blank=True, null=True) 101 major = models.CharField(verbose_name='所學專業', max_length=64, blank=True, null=True) 102 103 experience_choices = [ 104 (1, '在校生'), 105 (2, '應屆畢業'), 106 (3, '半年之內'), 107 (4, '半年至一年'), 108 (5, '一年至三年'), 109 (6, '三年至五年'), 110 (7, '五年以上'), 111 ] 112 experience = models.IntegerField(verbose_name='工做經驗', blank=True, null=True, choices=experience_choices) 113 work_status_choices = [ 114 (1, '在職'), 115 (2, '無業') 116 ] 117 work_status = models.IntegerField(verbose_name="職業狀態", choices=work_status_choices, default=1, blank=True, 118 null=True) 119 company = models.CharField(verbose_name="目前就任公司", max_length=64, blank=True, null=True) 120 salary = models.CharField(verbose_name="當前薪資", max_length=64, blank=True, null=True) 121 122 source_choices = [ 123 (1, "qq羣"), 124 (2, "內部轉介紹"), 125 (3, "官方網站"), 126 (4, "百度推廣"), 127 (5, "360推廣"), 128 (6, "搜狗推廣"), 129 (7, "騰訊課堂"), 130 (8, "廣點通"), 131 (9, "高校宣講"), 132 (10, "渠道代理"), 133 (11, "51cto"), 134 (12, "智匯推"), 135 (13, "網盟"), 136 (14, "DSP"), 137 (15, "SEO"), 138 (16, "其它"), 139 ] 140 source = models.SmallIntegerField('客戶來源', choices=source_choices, default=1) 141 referral_from = models.ForeignKey( 142 'self', 143 blank=True, 144 null=True, 145 verbose_name="轉介紹自學員", 146 help_text="若此客戶是轉介紹自內部學員,請在此處選擇內部學員姓名", 147 related_name="internal_referral" 148 ) 149 course = models.ManyToManyField(verbose_name="諮詢課程", to="Course") 150 151 status_choices = [ 152 (1, "已報名"), 153 (2, "未報名") 154 ] 155 status = models.IntegerField( 156 verbose_name="狀態", 157 choices=status_choices, 158 default=2, 159 help_text=u"選擇客戶此時的狀態" 160 ) 161 162 consultant = models.ForeignKey(verbose_name="課程顧問", to='UserInfo', related_name='consultanter',limit_choices_to={'depart':1001}) 163 164 date = models.DateField(verbose_name="諮詢日期", auto_now_add=True) 165 recv_date = models.DateField(verbose_name="當前課程顧問的接單日期", null=True) 166 last_consult_date = models.DateField(verbose_name="最後跟進日期", ) 167 168 def __str__(self): 169 return self.name 170 171 class ConsultRecord(models.Model): 172 """ 173 客戶跟進記錄 174 """ 175 customer = models.ForeignKey(verbose_name="所諮詢客戶", to='Customer') 176 consultant = models.ForeignKey(verbose_name="跟蹤人", to='UserInfo',limit_choices_to={'depart':1001}) 177 date = models.DateField(verbose_name="跟進日期", auto_now_add=True) 178 note = models.TextField(verbose_name="跟進內容...") 179 180 def __str__(self): 181 return self.customer.name + ":" + self.consultant.name 182 183 class Student(models.Model): 184 """ 185 學生表(已報名) 186 """ 187 customer = models.OneToOneField(verbose_name='客戶信息', to='Customer') 188 class_list = models.ManyToManyField(verbose_name="已報班級", to='ClassList', blank=True) 189 190 emergency_contract = models.CharField(max_length=32, blank=True, null=True, verbose_name='緊急聯繫人') 191 company = models.CharField(verbose_name='公司', max_length=128, blank=True, null=True) 192 location = models.CharField(max_length=64, verbose_name='所在區域', blank=True, null=True) 193 position = models.CharField(verbose_name='崗位', max_length=64, blank=True, null=True) 194 salary = models.IntegerField(verbose_name='薪資', blank=True, null=True) 195 welfare = models.CharField(verbose_name='福利', max_length=256, blank=True, null=True) 196 date = models.DateField(verbose_name='入職時間', help_text='格式yyyy-mm-dd', blank=True, null=True) 197 memo = models.CharField(verbose_name='備註', max_length=256, blank=True, null=True) 198 199 def __str__(self): 200 return self.customer.name 201 202 class ClassStudyRecord(models.Model): 203 """ 204 上課記錄表 (班級記錄) 205 """ 206 class_obj = models.ForeignKey(verbose_name="班級", to="ClassList") 207 day_num = models.IntegerField(verbose_name="節次", help_text=u"此處填寫第幾節課或第幾天課程...,必須爲數字") 208 teacher = models.ForeignKey(verbose_name="講師", to='UserInfo',limit_choices_to={'depart':1002}) 209 date = models.DateField(verbose_name="上課日期", auto_now_add=True) 210 211 course_title = models.CharField(verbose_name='本節課程標題', max_length=64, blank=True, null=True) 212 course_memo = models.TextField(verbose_name='本節課程內容概要', blank=True, null=True) 213 has_homework = models.BooleanField(default=True, verbose_name="本節有做業") 214 homework_title = models.CharField(verbose_name='本節做業標題', max_length=64, blank=True, null=True) 215 homework_memo = models.TextField(verbose_name='做業描述', max_length=500, blank=True, null=True) 216 exam = models.TextField(verbose_name='踩分點', max_length=300, blank=True, null=True) 217 218 def __str__(self): 219 return "{0} day{1}".format(self.class_obj, self.day_num) 220 221 class StudentStudyRecord(models.Model): 222 ''' 223 學生學習記錄 224 ''' 225 classstudyrecord = models.ForeignKey(verbose_name="第幾天課程", to="ClassStudyRecord") 226 student = models.ForeignKey(verbose_name="學員", to='Student') 227 228 229 230 231 232 233 234 record_choices = (('checked', "已簽到"), 235 ('vacate', "請假"), 236 ('late', "遲到"), 237 ('noshow', "缺勤"), 238 ('leave_early', "早退"), 239 ) 240 record = models.CharField("上課紀錄", choices=record_choices, default="checked", max_length=64) 241 score_choices = ((100, 'A+'), 242 (90, 'A'), 243 (85, 'B+'), 244 (80, 'B'), 245 (70, 'B-'), 246 (60, 'C+'), 247 (50, 'C'), 248 (40, 'C-'), 249 (0, ' D'), 250 (-1, 'N/A'), 251 (-100, 'COPY'), 252 (-1000, 'FAIL'), 253 ) 254 score = models.IntegerField("本節成績", choices=score_choices, default=-1) 255 homework_note = models.CharField(verbose_name='做業評語', max_length=255, blank=True, null=True) 256 note = models.CharField(verbose_name="備註", max_length=255, blank=True, null=True) 257 258 homework = models.FileField(verbose_name='做業文件', blank=True, null=True, default=None) 259 stu_memo = models.TextField(verbose_name='學員備註', blank=True, null=True) 260 date = models.DateTimeField(verbose_name='提交做業日期', auto_now_add=True) 261 262 def __str__(self): 263 return "{0}-{1}".format(self.classstudyrecord, self.student) 264 265 """ 266 chocies參數使用場景是很是普遍的 267 """
1 # MTV:Django號稱是MTV模型 2 M:models 3 T:templates 4 V:views 5 # MVC:其實django本質也是MVC 6 M:models 7 V:views 8 C:controller 包括(urls.py)控制器 9 10 # vue框架:MVVM模型
1 # 全自動:利用orm自動幫咱們建立第三張關係表 2 class Book(models.Model): 3 name = models.CharField(max_length=32) 4 authors = models.ManyToManyField(to='Author') 5 class Author(models.Model): 6 name = models.CharField(max_length=32) 7 """ 8 優勢:代碼不須要你寫 很是的方便 還支持orm提供操做第三張關係表的方法... 9 不足之處:第三張關係表的擴展性極差(沒有辦法額外添加字段...) 10 """ 11 # 純手動 12 class Book(models.Model): 13 name = models.CharField(max_length=32) 14 15 class Author(models.Model): 16 name = models.CharField(max_length=32) 17 18 class Book2Author(models.Model): 19 book_id = models.ForeignKey(to='Book') 20 author_id = models.ForeignKey(to='Author') 21 ''' 22 優勢:第三張表徹底取決於你本身進行額外的擴展 23 不足之處:須要寫的代碼較多,不可以再使用orm提供的簡單的方法 24 不建議你用該方式 25 ''' 26 27 # 半自動 28 class Book(models.Model): 29 name = models.CharField(max_length=32) 30 authors = models.ManyToManyField(to='Author', 31 through='Book2Author', 32 through_fields=('book','author') 33 ) 34 class Author(models.Model): 35 name = models.CharField(max_length=32) 36 # books = models.ManyToManyField(to='Book', 37 # through='Book2Author', 38 # through_fields=('author','book') 39 # ) 40 class Book2Author(models.Model): 41 book = models.ForeignKey(to='Book') 42 author = models.ForeignKey(to='Author') 43 44 """ 45 through_fields字段前後順序 46 判斷的本質: 47 經過第三張表查詢對應的表 須要用到哪一個字段就把哪一個字段放前面 48 你也能夠簡化判斷 49 當前表是誰 就把對應的關聯字段放前面 50 51 52 半自動:可使用orm的正反向查詢 可是無法使用add,set,remove,clear這四個方法 53 """ 54 55 # 總結:你須要掌握的是全自動和半自動 爲了擴展性更高 通常咱們都會採用半自動(寫代碼要給本身留一條後路)
only與defer ''' only 只有only括號內的字段在查詢出的對象中,查詢該字段無需走數據庫,查詢其餘字段須要重走數據庫查詢操做 defer:效果與only相反 只有在查詢defer括號內的字段時纔會走數據庫查詢操做 ''' select_related與prefetch_related 跟跨表操做有關 ''' select_related與prefetch_related查詢完就不走數據庫操做,由於數據全都封裝在獲得的對象中了 select_related:內部就是聯表操做,將關聯後的大表內的數據全都封裝到對象中 注意:select_related括號內只能一對一或者多對一關係的字段, 放多對多關係或者非外鍵字段就會報錯 prefetch_related:內部就是子查詢,一樣也會將數據全都封裝到對象中 select_related與prefetch_related各有優缺點,具體用誰得結合實際狀況 '''
""" 爲了創建冗餘較小、結構合理的數據庫,設計數據庫時候要遵循必定的規則。在關係型數據庫中這種規則被稱爲範式。 """ 第一範式(1NF) 第一範式是最基本的範式。 ''' 定義:若是數據庫表中的每一個字段(列)的屬性值都是不分解的原子項,那麼該數據表就知足第一範式(1NF)。 第一範式書面話:必須保證數據庫表的每一字段(列)都是不可分割的基本數據項 大白話:必須保證每張表的每一個字段(列)都不可再分 ''' 以下表: ------------------------------------------------------ 學號 姓名 性別 聯繫方式 111 jason 男 110,111@qq.com 222 egon 女 120,222@qq.com ------------------------------------------------------ 上述的表就不知足第一範式,聯繫方式字段還能夠再分,能夠分爲以下: ------------------------------------------------------ 學號 姓名 性別 電話 郵箱 111 jason 男 110 111@qq.com 222 egon 女 120 222@qq.com ------------------------------------------------------ 第二範式(2NF) ''' 第二範式書面話:必須知足第一範式 保證每一行都要有惟一標識存在, 這個惟一屬性列被稱爲主關鍵字或主鍵、主碼。 實體的屬性徹底依賴於主關鍵字。 大白話:必須知足第一範式,必須保證每張表內都有主鍵,且非主鍵字段必須依賴主鍵字段 ''' 好比學生選課表: --------------------------------------------------- 學生 課程 教師 教室 教材 菲菲 python jason 111 《python基礎》 思思 linux egon 222 《數據分析》 --------------------------------------------------- 這裏經過(學生,課程)能夠肯定教師、教材和教室,因此能夠把(學生,課程)做爲聯合主鍵。 可是教材並不徹底依賴於(學生,課程),只拿出課程就能夠肯定教材,由於一個課程,必定指定了 某個教材。這就叫不徹底相關,或者部分相關。出現這種狀況,就不知足第二範式。 第三範式(3NF) ''' 定義:知足2NF後,要求表中的全部列,都必須依賴於主鍵,而不能有任何一列與主鍵沒有關係,也就是說一個表只描述一件事情; 大白話:就是在一個數據庫表中,一個表中只能保存一種數據,不能夠把多種數據保存在同一張數據庫表中。 非主鍵列必須直接依賴於主鍵,不能存在傳遞依賴。即不能存在:非主鍵列 A 依賴於非主鍵列 B,非主鍵列 B 依賴於主鍵的狀況。 ''' 修改後, 選課表: --------------------------------- 學生 課程 教師 教室 菲菲 python jason 111 思思 linux egon 222 --------------------------------- 課程表: ------------------------------ 課程 教材 python 《python基礎》 linux 《數據分析》 ------------------------------- 如何更好的區分三大範式 ''' 第 一範式和第二範式在於有沒有分出兩張表, 第二範式是說一張表中包含了所種不一樣的實體屬性,那麼要必須分紅多張表, 第三範式是要求已經分紅了多張表,那麼一張表中只能有另外一張表中的id(主鍵), 而不能有其餘的任何信息(其餘的信息一概用主鍵在另外一表查詢)。 '''
1 """ 2 異步提交 3 局部刷新 4 例子:github註冊 5 動態獲取用戶名實時的跟後端確認並實時展現的前端(局部刷新) 6 7 朝發送請求的方式 8 1.瀏覽器地址欄直接輸入url回車 GET請求 9 2.a標籤href屬性 GET請求 10 3.form表單 GET請求/POST請求 11 4.ajax GET請求/POST請求 12 13 AJAX 不是新的編程語言,而是一種使用現有標準的新方法(比較裝飾器) 14 15 16 AJAX 最大的優勢是在不從新加載整個頁面的狀況下,能夠與服務器交換數據並更新部分網頁內容。(這一特色給用戶的感覺是在不知不覺中完成請求和響應過程) 17 18 19 Ajax咱們只學習jQuery封裝以後的版本(不學原生的 原生的複雜而且在實際項目中也通常不用) 20 因此咱們在前端頁面使用ajax的時候須要確保導入了jQuery 21 ps:並不僅有jQuery可以實現ajax,其餘的框架也能夠 可是換湯不換藥 原理是同樣的 22 """
1 """ 2 頁面上有三個input框 3 在前兩個框中輸入數字 點擊按鈕 朝後端發送ajax請求 4 後端計算出結果 再返回給前端動態展現的到第三個input框中 5 (整個過程頁面不許有刷新,也不能在前端計算) 6 """ 7 $('#btn').click(function () { 8 // 朝後端發送ajax請求 9 $.ajax({ 10 // 1.指定朝哪一個後端發送ajax請求 11 url:'', // 不寫就是朝當前地址提交 12 // 2.請求方式 13 type:'post', // 不指定默認就是get 都是小寫 14 // 3.數據 15 {#data:{'username':'jason','password':123},#} 16 data:{'i1':$('#d1').val(),'i2':$('#d2').val()}, 17 dataType: 'json', 18 // 4.回調函數:當後端給你返回結果的時候會自動觸發 args接受後端的返回結果 19 success:function (args) { 20 {#alert(args) // 經過DOM操做動態渲染到第三個input裏面#} 21 {#$('#d3').val(args)#} 22 console.log(typeof args) 23 24 } 25 }) 26 }) 27 28 29 """ 30 針對後端若是是用HttpResponse返回的數據 回調函數不會自動幫你反序列化 31 若是後端直接用的是JsonResponse返回的數據 回調函數會自動幫你反序列化 32 33 HttpResponse解決方式 34 1.本身在前端利用JSON.parse() 35 2.在ajax裏面配置一個參數 36 (後面再講) 37 """
今日做業 必作題 1.整理今日內容 用本身的話術整理到博客中(切勿直接複製粘貼) 2.orm數據庫查詢優化及數據庫三大設計範式自我概括總結 3.體會choices參數在實際項目中的具體應用場景 選作 4.利用ajax完成數據的二次確認刪除