django-模型层续续

Posted wgwg

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了django-模型层续续相关的知识,希望对你有一定的参考价值。

今日内容概要

  • 图书管理的图书增删改查
  • choices参数(数据库字段设计常见)
  • MTV与MVC模型
  • 多对多关系的三种创建方式
  • 数据库的三大设计范式

  • Ajax操作(重点)
  • ajax发送json格式数据

图书管理的图书增删改查

urls.py

技术图片urls.py

models.py

技术图片models.py

views.py

技术图片views.py

home.html

技术图片home.html

book_list.html

技术图片book_list.html

book_edit.html

技术图片book_edit,html

book_add.html

技术图片book_add.html

choices参数(数据库字段设计常见)

 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 """
实际项目案例-CRM相关内部表

MTV与MVC模型

 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 # 总结:你需要掌握的是全自动和半自动 为了扩展性更高 一般我们都会采用半自动(写代码要给自己留一条后路)

 

orm数据库查询优化

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(主键),
而不能有其他的任何信息(其他的信息一律用主键在另一表查询)。
‘‘‘

  

Ajax

 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完成数据的二次确认删除

  

 

"""

以上是关于django-模型层续续的主要内容,如果未能解决你的问题,请参考以下文章

Django REST框架--认证和权限

如何在Django视图中使用for循环返回每次迭代[关闭]

如何在 Django Summernote 中显示编程片段的代码块?

Django管理图标和图像

django.core.exceptions.ImproperlyConfigured: Requested setting DEFAULT_INDEX_TABLESPACE的解决办法(转)(代码片段

django.core.exceptions.ImproperlyConfigured: Requested setting DEFAULT_INDEX_TABLESPACE的解决办法(转)(代码片段