day66——choices参数、MTV/MVC模型、三种创建多对多的方式、AJAX
redirect补充:
redirect括号里可以直接写url,还可以写url的别名,它会自动进行反向解析然后帮你跳转。但是如何url是有名分组或者是无名分组的情况,别名需要额外的参数redirect则无法实现,还是得使用reverse进行反向解析。
choices参数
针对某个可以列举完全可能性的字段,一般会采用choices参数来存储;通过存数字或者字母、简单的单词来对应数据的详细解释;比如客户表中的表示性别字段(男/女),或者是成绩表的成绩(优良中差)。
class User(request):
username = models.CharField(max_length=32)
# 用元组列举完客户性别的可能性,元组内第一个参数是字段的的值,第二个参数是对应的解释/内容。
gender_choices = (
(1,'男'),
(2,'女'),
)
# 创建字段时字段的类型取决于元组内第一个参数的数据类型
gender = models.IntegerField(choices = gender_choices) # 整型字段
class Student(models.Model):
name = models.CharField(max_length=32)
score_choices =(
('A', '优秀'),
('B', '良好'),
('C', '中等'),
('D', '不及格'),
)
score = models.CharField(max_length=32, choices=score_choices) # 字符字段,字段该传的参数还的传
指定choice参数的字段存数据的范围还是取决于字段本身的类型,就是说不管有没有在元组里列举出来,只要数据的类型相同且在字段的最大限制范围内都是可以存储的,只不过存元组列举范围内的数据可以非常轻松的获取到数字/字母对应真正的内容。choice字段取值固定句式.get_字段名_display()
# 存数据
models.User.objects.create(username='jason',gender=1)
models.User.objects.create(username='egon',gender=2)
models.User.objects.create(username='tank',gender=3) # 不再元组列举的范围内也能存储
"""
gender
1
2
3
"""
# 取值
user_obj1=models.User.objects.filter(pk=1).first()
user_obj2=models.User.objects.filter(pk=3).first()
print(user_obj1.get_gender_display()) # 男 在元组的列举范围内取具体的内容
print(user_obj2.get_gender_display()) # 3 在元组的列举范围内取原本存入的数据
choices参数的使用场景非常广泛。
# 学历
education_choices = (
(1, '重点大学'),
(2, '普通本科'),
(3, '独立院校'),
(4, '民办本科'),
(5, '大专'),
(6, '民办专科'),
(7, '高中'),
(8, '其他')
)
# 工作经验
experience_choices = [
(1, '在校生'),
(2, '应届毕业'),
(3, '半年以内'),
(4, '半年至一年'),
(5, '一年至三年'),
(6, '三年至五年'),
(7, '五年以上'),
]
MTV与MVC模型
-
MTV:Django号称是MTV模型,其实本质上也是MVC模型
- M:models
- T:templates
- V:views
-
MVC: 设计模型是一种使用 Model View Controller( 模型-视图-控制器)设计创建 Web 应用程序的模式。
多对多三种创建方式
-
纯手动
自己创建第三张关系表,在关系表中书写外键字段(基本不用)
class Book(models.Model): title = models.CharField(max_length=32) class Author(models.Model): name = models.CharField(max_length=32) class Book2Author(models.Model): # 手动建关系表 book_id = models.ForeignKey(to='Book') # 关系表中自己建外键字段 author_id = models.ForeignKey(to='Author') related_time = models.DateField(auto_now=True) # 扩展字段
优点:
第三张关系表可以根据自己的需求进行额外的扩展,比如增加一个两表关系的更新时间
缺点:
需要书写的代码较多,且不能使用orm提供的简单的方法,使用起来非常麻烦。
-
全自动
无需直接建关系表,让orm自动帮助我们创建。
class Book(models.Model): title = models.CharField(max_length=32) authors = models.ManyToManyField(to='Author') # 虚拟的外键字段,告诉orm创建关系表 class Author(models.Model): name = models.CharField(max_length=32)
优点:
关系表不用自己创建,且支持orm提供操作第三张关系表的方法,使用起来非常方便
缺点:
第三张关系表的扩展性极差(无法增加额外的字段)
-
半自动
需要建关系表提升扩展性,并且还可以在基表内建外键。
class Book(models.Model): title = models.CharField(max_length=32) authors = models.ManyToManyField(to='Author', through='Book2Author', through_fileds=('book','author')) # 告诉orm通过哪张表建立关系 class Author(models.Model): name = models.CharField(max_length=32) class BookAuthor(models.Model): book = models.ForeignKey(to='Book') author = models.ForeignKey(to='Author')
优点:
扩展高并且能够使用orm操作第三张表的方法,支持正反向查询。
缺点:
add,set,remove,clear这四个方法不能使用。
through_fileds
字段参数的先后顺序:-
判断的本质:通过第三张关系表查询对应的表,需要用哪个字段就把哪个字段放在前面
-
简化判断:当前表是谁,就把对应的关键字放在前面
-
AJAX
Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),AJAX并不是一门新的编程语言,而是一种使用现有标注的新方法(跟装饰器类似)。它能够向后端提供GET请求/POST请求,提交异步请求,实现局部更新的效果。
效果可参照github的登录界面,实时显示用户名是否也存在或者是否合法。
优点:
在不重新加载页面的情况下,可以跟服务器进行数据的交互并更新部分页面内容,这一特点给用户的感受是在不知不觉中完成请求和响应过程。
jax我们只学习jQuery封装之后的版本,简单一点,所以在使用AJAX前,确保了JQuery,
并不只有jQuery能够实现ajax,其他的框架也可以 但是换汤不换药 原理是一样的。
AJAX基本语法
$.ajax({
url:'', # 指定提交的后端地址
type:'post', # 提交请求方式址
data:, # 提交的数据
success:function(args){ # 4.回调函数:当后端给你返回结果的时候会自动触发 args接受后端的返回结果
alert('111')
}
})
小例子
前两个input输入数字点击求和按钮,页面不刷新的情况下,在第三个框展示结果,健壮性先不考虑,体会AJAX的特性
路由:
url(r'^simple_sum/',views.simple_sum,name='simple_sum')
后端:
def simple_sum(request):
import json
if request.method=='POST':
i1=request.POST.get('i1')
i2=request.POST.get('i2')
i3 = int(i1)+int(i2)
return HttpResponse(i3)
return render(request,'simple_sum.html')
前端页面:
<body>
<div class="container">
<div class="row">
<input type="text" id="d1" name="i1">+
<input type="text" id="d2" name="i2">=
<input type="text" id="d3">
<button class="btn btn-success">求和</button>
</div>
</div>
<script>
$('.btn').click(function () {
$.ajax({
url:'',
data: {'i1':$('#d1').val(),'i2':$('#d2').val()},
type:'post',
dataType:'json',
success:function (args) {
$('#d3').val(args)
}
})
})
</script>
</body>
回调函数的是否自动序列化
-
针对后端如果是用HttpResponse返回的数据,回调函数不会自动帮你反序列化
解决办法:
- 自己在前端利用JSON.parse()
- 在ajax里面配置一个参数,
dataType:'json'
-
如果后端直接用的是JsonResponse返回的数据,回调函数会自动帮你反序列化