一、choices参数的使用
python
choices它是ORM中常用字段中的参数
choices的作用:
类似于一些字段:性别、学历、客户来源、是否上学、是否结婚等字段
# 针对于一些字段它的情况能够被列举完,像这样的字段,我们在表中存储的时候一般使用choices参数
案例
class Customer(models.Model):
"""
客户表
"""
qq = models.CharField(verbose_name='qq', max_length=64, unique=True, help_text='QQ号必须唯一')
name = models.CharField(verbose_name='学生姓名', max_length=16)
gender_choices = ((1, '男'), (2, '女'))
gender = models.SmallIntegerField(verbose_name='性别', choices=gender_choices)
education_choices = (
(1, '重点大学'),
(2, '普通本科'),
(3, '独立院校'),
(4, '民办本科'),
(5, '大专'),
(6, '民办专科'),
(7, '高中'),
(8, '其他')
)
education = models.IntegerField(verbose_name='学历', choices=education_choices, blank=True, null=True, )
graduation_school = models.CharField(verbose_name='毕业学校', max_length=64, blank=True, null=True)
major = models.CharField(verbose_name='所学专业', max_length=64, blank=True, null=True)
experience_choices = [
(1, '在校生'),
(2, '应届毕业'),
(3, '半年以内'),
(4, '半年至一年'),
(5, '一年至三年'),
(6, '三年至五年'),
(7, '五年以上'),
]
experience = models.IntegerField(verbose_name='工作经验', blank=True, null=True, choices=experience_choices)
work_status_choices = [
(1, '在职'),
(2, '无业')
]
work_status = models.IntegerField(verbose_name="职业状态", choices=work_status_choices, default=1, blank=True,
null=True)
company = models.CharField(verbose_name="目前就职公司", max_length=64, blank=True, null=True)
salary = models.CharField(verbose_name="当前薪资", max_length=64, blank=True, null=True)
source_choices = [
(1, "qq群"),
(2, "内部转介绍"),
(3, "官方网站"),
(4, "百度推广"),
(5, "360推广"),
(6, "搜狗推广"),
(7, "腾讯课堂"),
(8, "广点通"),
(9, "高校宣讲"),
(10, "渠道代理"),
(11, "51cto"),
(12, "智汇推"),
(13, "网盟"),
(14, "DSP"),
(15, "SEO"),
(16, "其它"),
]
source = models.SmallIntegerField('客户来源', choices=source_choices, default=1)
referral_from = models.ForeignKey(
'self',
blank=True,
null=True,
verbose_name="转介绍自学员",
help_text="若此客户是转介绍自内部学员,请在此处选择内部学员姓名",
related_name="internal_referral"
)
course = models.ManyToManyField(verbose_name="咨询课程", to="Course")
status_choices = [
(1, "已报名"),
(2, "未报名")
]
status = models.IntegerField(
verbose_name="状态",
choices=status_choices,
default=2,
help_text=u"选择客户此时的状态"
)
consultant = models.ForeignKey(verbose_name="课程顾问", to='UserInfo', related_name='consultanter',
limit_choices_to={'depart': 1001})
date = models.DateField(verbose_name="咨询日期", auto_now_add=True)
recv_date = models.DateField(verbose_name="当前课程顾问的接单日期", null=True)
last_consult_date = models.DateField(verbose_name="最后跟进日期", )
def __str__(self):
return self.name
class ConsultRecord(models.Model):
"""
客户跟进记录
"""
customer = models.ForeignKey(verbose_name="所咨询客户", to='Customer')
consultant = models.ForeignKey(verbose_name="跟踪人", to='UserInfo', limit_choices_to={'depart': 1001})
date = models.DateField(verbose_name="跟进日期", auto_now_add=True)
note = models.TextField(verbose_name="跟进内容...")
def __str__(self):
return self.customer.name + ":" + self.consultant.name
class Student(models.Model):
"""
学生表(已报名)
"""
customer = models.OneToOneField(verbose_name='客户信息', to='Customer')
class_list = models.ManyToManyField(verbose_name="已报班级", to='ClassList', blank=True)
emergency_contract = models.CharField(max_length=32, blank=True, null=True, verbose_name='紧急联系人')
company = models.CharField(verbose_name='公司', max_length=128, blank=True, null=True)
location = models.CharField(max_length=64, verbose_name='所在区域', blank=True, null=True)
position = models.CharField(verbose_name='岗位', max_length=64, blank=True, null=True)
salary = models.IntegerField(verbose_name='薪资', blank=True, null=True)
welfare = models.CharField(verbose_name='福利', max_length=256, blank=True, null=True)
date = models.DateField(verbose_name='入职时间', help_text='格式yyyy-mm-dd', blank=True, null=True)
memo = models.CharField(verbose_name='备注', max_length=256, blank=True, null=True)
def __str__(self):
return self.customer.name
class ClassStudyRecord(models.Model):
"""
上课记录表 (班级记录)
"""
class_obj = models.ForeignKey(verbose_name="班级", to="ClassList")
day_num = models.IntegerField(verbose_name="节次", help_text=u"此处填写第几节课或第几天课程...,必须为数字")
teacher = models.ForeignKey(verbose_name="讲师", to='UserInfo', limit_choices_to={'depart': 1002})
date = models.DateField(verbose_name="上课日期", auto_now_add=True)
course_title = models.CharField(verbose_name='本节课程标题', max_length=64, blank=True, null=True)
course_memo = models.TextField(verbose_name='本节课程内容概要', blank=True, null=True)
has_homework = models.BooleanField(default=True, verbose_name="本节有作业")
homework_title = models.CharField(verbose_name='本节作业标题', max_length=64, blank=True, null=True)
homework_memo = models.TextField(verbose_name='作业描述', max_length=500, blank=True, null=True)
exam = models.TextField(verbose_name='踩分点', max_length=300, blank=True, null=True)
def __str__(self):
return "{0} day{1}".format(self.class_obj, self.day_num)
class StudentStudyRecord(models.Model):
'''
学生学习记录
'''
classstudyrecord = models.ForeignKey(verbose_name="第几天课程", to="ClassStudyRecord")
student = models.ForeignKey(verbose_name="学员", to='Student')
record_choices = (('checked', "已签到"),
('vacate', "请假"),
('late', "迟到"),
('noshow', "缺勤"),
('leave_early', "早退"),
)
record = models.CharField("上课纪录", choices=record_choices, default="checked", max_length=64)
score_choices = ((100, 'A+'),
(90, 'A'),
(85, 'B+'),
(80, 'B'),
(70, 'B-'),
(60, 'C+'),
(50, 'C'),
(40, 'C-'),
(0, ' D'),
(-1, 'N/A'),
(-100, 'COPY'),
(-1000, 'FAIL'),
)
score = models.IntegerField("本节成绩", choices=score_choices, default=-1)
homework_note = models.CharField(verbose_name='作业评语', max_length=255, blank=True, null=True)
note = models.CharField(verbose_name="备注", max_length=255, blank=True, null=True)
homework = models.FileField(verbose_name='作业文件', blank=True, null=True, default=None)
stu_memo = models.TextField(verbose_name='学员备注', blank=True, null=True)
date = models.DateTimeField(verbose_name='提交作业日期', auto_now_add=True)
def __str__(self):
return "{0}-{1}".format(self.classstudyrecord, self.student)
-------------------------------------------------------------------------------
test中制作测试环境
import os
import sys
if __name__ == '__main__':
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'day61.settings')
import django
django.setup()
from app01 import models
# 1.增加数据
# models.UserInfo.objects.create(username='张三', gender=1)
# models.UserInfo.objects.create(username='李四', gender=2)
# models.UserInfo.objects.create(username='王五', gender=3)
# models.UserInfo.objects.create(username='赵六', gender=4)
# 2.读取数据
# res = models.UserInfo.objects.filter(pk=1).first()
# 如果使用get就得抛出,否则获取不到数据会报错
try:
res = models.UserInfo.objects.get(pk=1)
print(res)
# 取值时不推荐使用这种
# if res.gender == 1:
# gender = '男'
# elif res.gender == 2:
# gender = '女'
# else:
# gender = '未知'
# 推荐使用
print(res.get_gender_display()) # 男
except Exception as e:
print(e, '该数据不存在')
二、MTV和MVC的概念
python
把Django框架的执行流程做分层
在Django中分的是MTV
在其他语言中分的是MVC
# 这两个本质上都是一样的
Web服务器开发领域里著名的MVC模式,所谓MVC就是把Web应用分为模型(M),控制器(C)和视图(V)三层,
Web服务器开发领域里著名的MTV模式,所谓MVC就是把Web应用分为模型(M),控制器(V)和视图(T)三层,
# Java、PHP文件名的命名是:
Login.Controller.java
Login.Controller.php
● M 代表模型(Model): 负责业务对象和数据库的关系映射(ORM)。
● T 代表模板 (Template):负责如何把页面展示给用户(html)。
● V 代表视图(View): 负责业务逻辑,并在适当时候调用Model和Template。
● S 代表视图(Services): 只有在业务逻辑相当复杂的时候,才分这一层,服务层,专门用来写业务逻辑
三、多对多的三种创建方式
python
多对多的关系是借助于第三张表实现的
通过一个虚拟字段创建的第三张表:authors = models.ManyToManyField(to='') # 全自动的
多对多的创建方式
方式一:全自动
class Book(models.Model):
title = models.CharField(max_length=64)
# 全自动创建多对多的关系
'''
特点:第三张表不需要我们自己来创建,通过这个虚拟字段自动创建出来第三张表
authors字段不会再表中创建出来字段
那么以后你在查询的时候,可以使用正反向查询和那四个方法 add set remove clear
它的劣势就是:表的扩展性很差
'''
# 若使用手动创建第三张表,则这个authors就不需要了
# authors = models.ManyToManyField(to='Author', through='Book2Author', through_fields=('book','author'))
class Author(models.Model):
name = models.CharField(max_length=128)
'''
through_fields的意思是指定第三张表中的哪些字段需要添加关系字段
注意:models.ManyToManyField 这句话写在作者表,
那么through_fields中的顺序就是先author再book,
反之就是先book再author
'''
books = models.ManyToManyField(to='Book', through='Book2Author', through_fields=('author','book'))
方式二:全手动
第三张表需要我们自己手动创建,不会在自动创建了
'''
优势:扩展性非常好
劣势:不能使用四个方法 add set remove clear
需要使用create、update、delete
'''
# class Book2Author(models.Model):
# book = models.ForeignKey(to='Book', on_delete=models.CASCADE)
# author = models.ForeignKey(to='Author', on_delete=models.CASCADE)
# create_time = models.DateTimeField(auto_now_add=True)
方式三:
半自动:支持正反向查询的,但是不支持那四个方法
class Book2Author(models.Model):
book = models.ForeignKey(to='Book', on_delete=models.CASCADE)
author = models.ForeignKey(to='Author', on_delete=models.CASCADE)
create_time = models.DateTimeField(auto_now_add=True)
四、Ajax技术简介
python
Ajax属于是前端的内容,不属于Python范围的,但是它必须结合后端来使用,否则也没有太大的意义,因为它是把前端的数据提交到后端的
form表单来提交数据到后端,但是,它每次提交数据都需要刷新页面,如果都刷新页面体验就不好
Ajax技术就是局部刷新,异步提交,它不需要刷新整个页面,只需要刷新局部的,主要就是刷新的时候是无感知的
Ajax的特点:
局部刷新
异步提交
案例:Github的注册案例
基于jquery的Ajax实现
# 我们知道Ajax它js是语言,所以它肯定能够使用js实现,但是,js实现太麻烦了,总共分四个步骤
# 我们不学学习js版本的ajax,我们学习jQuery封装之后的Ajax,把Ajax的使用表的非常简单
23种设计模式:单例模式,工厂模式,注册树模式等等
Ajax使用小案例
python
我们使用的ajax是jQuery封装之后的版本,所以,要想使用Ajax必须导入jQuery库
语法:
$.ajax({
// 1. 指定参数提交到后端的哪个地址?
url:'', // 如果不写就是朝当前地址提交
// 2. 指定以什么请求方式提交的 get post
type:'post',
// 3. 指定要传递的数据
data: {},
//dataType:'json', //指定序列化格式
// 4. 回调函数,接收后端返回的数据
success:function (res) {}
})
views.py中的代码:
def index(request):
# print(request.is_ajax()) # True False
if request.method == 'POST':
# 接收参数
# d1 = request.POST.get('d1')
# d2 = request.POST.get('d2')
#
# # 做运算
# d3 = int(d1) + int(d2)
d = {'code': 200, 'msg': '请求方式', 'data': {'username': '老林'}}
# return HttpResponse(d3)
import json
res = json.dumps(d, ensure_ascii=False)
'''
若前端不想使用JSON.parse(res),且后端还使用HttpResponse(res),
则在前端加上 dataType: 'json' 指定json格式
'''
return HttpResponse(res)
# '''
# 如果后端使用了JsonResponse(d),则前端不需要JSON.parse(res)
# '''
# return JsonResponse(d)
return render(request, 'index.html')
前端页面的代码:
<input type="text" id="d1">+
<input type="text" id="d2">=
<input type="text" id="d3">
<button class="btn btn-info">计算</button>
{# 绑定事件 #}
<script>
$('.btn').click(function (){
//获取两个输入框中的值
var d1 = $("#d1").val();
var d2 = $("#d2").val();
//把前端输入的值提交到后端计算
//问题是如何提交到后端
//使用ajax提交
$.ajax({
// 1.指定参数提交到后端的哪个地址?
url: '', // 如果不写就是朝当前地址提交
// 2.指定以什么请求方式提交的 get post,如果不指定就是get
type: 'post',
// 3.指定药传递的数据
data: {d1: d1, d2: d2},
{#data: {'d1': d1, 'd2': d2},#}
dataType: 'json', {# 不使用 res = JSON.parse(res)序列化,但是还需要使用HttpResponse()时就使用这个指定格式 #}
// 4.回调函数:接收后端返回的数据
success: function (res){
{#console.log(res);#}
{#console.log(typeof res);#}
{# 设置d3的value值 #}
{#$('#d3').val(res)#}
{# 前端怎么反序列化? #}
{#res = JSON.parse(res)#}
console.log(res)
console.log(typeof res)
console.log(res.code)
console.log(res.data)
console.log(res.data.username)
console.log(res.msg)
},
})
})
</script>
总结:
1. 后端如果使用return JsonResponse(d), 前端不用反序列化,直接当成对象使用
2. 后端使用return HttpResponse(res),前端需要自己反序列化:res= JSON.parse(res)
3. 后端使用return HttpResponse(res),前端不反序列化,需要指定参数:dataType:'json'
name属性和value属性
python
name 属性:
name 属性用于标识表单字段的名称,这个名称在提交表单时将作为数据的键名传递给服务器。
每个表单字段(如输入框、复选框、单选按钮等)都应该有一个唯一的 name 属性。
通过 name 属性,服务器端脚本或后端应用程序可以识别和获取相应的表单数据。
在 HTML 表单中,表单字段的 name 属性通常结合服务器端代码来处理表单数据,例如 PHP、ASP.NET、Node.js 等。
value 属性:
value 属性定义表单字段的初始值,或者在用户输入数据后,将包含用户输入的值。
对于文本输入框、密码框、文本区域等,value 属性设置默认文本或用户已输入的文本。
对于单选按钮和复选框,value 属性指定了该选项提交时传递给服务器的值。
对于下拉菜单(<select> 元素),value 属性指定每个选项的值。
用户在表单字段中输入的数据将会覆盖 value 属性中设置的默认值。