python课程典范选优_【实战演练】Python+Django网站开发系列10-课程选课与退选业务逻辑添加...

#本文欢迎转载,转载请注明出处和作者

课程选课页面,会用到查询后台数据库信息并且返回给前端展示,然后前端有按钮可以点击需要选修的课程,然后返回给后台写入数据库记录。是之前08、09的两篇的实际应用案例:Python+Django网站开发系列08-JavaScript/JQuery前后端交互​zhuanlan.zhihu.comzhihu-card-default.svgPython+Django网站开发系列09-django前端展示后台数据​zhuanlan.zhihu.comzhihu-card-default.svg

1、课程选课页面展示

依然在magicbox里面选取表格组件,这次我们选择一个带按钮的表格样式,方便后面做选课,然后复制代码粘贴到stuinfo/tchinfo的html页面。(就是

{% extends 'BASE02.html' %}

{% block content %}

课程ID

课程名称

学分

上课时间

上课地点

操作

{% for i in courseinfo %}

{{ i.cno }}

{{ i.cname }}

{{ i.ccredit }}

{{ i.ctime }}

{{ i.cplace }}

{% endfor %}

{% endblock %}

函数增加查询后台数据库表全部数据,并且返回给前端页面。

def selcourse(request):

courseinfo = course.objects.all()

return render_to_response('selcourse.html',locals())

效果如下:

2、按钮点击JS

2.1选课按钮业务逻辑

选课按钮的业务逻辑,有了前面的基础,就非常好弄了,与之前修改密码一样,通过JS进行编写,编写stumgrjs.js文件,增加addcourse函数。(也是通过.post向后台推送数据)

JS函数,注意也需要带参数输入,括号里面有个参数,将课程ID推送到selcourse后台函数。

function addcourse(cno) {

$.post('/selcourse/', {

'cno':cno,

}, function (res) {

if(res.result){

alert("选课成功!");

window.location.reload();

}else{

alert("选课失败!");

window.location.reload();

}

}, 'json')

}

修改selcourse业务逻辑:这里涉及ORM查询数据库操作,而且课程表(course)与学生表(course)之间是没有直接关联的,是通过中间表-成绩表(score)进行关联的,所以需要插入数据的是score表。

def selcourse(request):

if request.method == 'POST' and request.POST:

cno = request.POST['cno']

username = request.session['username']

user = student.objects.get(username=username)

sno = user.sno

score.objects.create(cno_id=cno,sno_id=sno)

result = True

return JsonResponse({'result': result})

courseinfo = course.objects.all()

return render_to_response('selcourse.html',locals())

先查询当前登录用户的sno,然后cno与sno一切写入score表,创建一条数据,注意当前score表里面的sno叫sno_id,cno叫cno_id,因为是外键引用,所以会自动改了字段名。

前端selcourse.html页面按钮编辑:与之前的onclick唯一的区别,就是调用的js函数可以带参数将'{{ i.cno }}'输入到JS函数,然后JS将cno这个id字段通过post返回给后台,这样后台就能够知道是要选修哪一门课程了。

但是当前的业务逻辑存在Bug,1是同一个的课程可以多次选修,2是每个人可以无限选修课程。需要继续优化业务逻辑。

def selcourse(request):

if request.method == 'POST' and request.POST:

cno = request.POST['cno']

username = request.session['username']

user = student.objects.get(username=username)

sno = user.sno

# 判断当前课程是否已经选修

selected = score.objects.filter(cno_id=cno,sno_id=sno)

# 技术已选课程数量,counted.count()直接统计数字

counted = score.objects.filter(sno_id=sno)

if selected:

result = '课程已选修,请勿重复选择!'

return JsonResponse({'result': result})

elif counted.count() >=2:

result = '已达到最大选修课程数量!'

return JsonResponse({'result': result})

else:

#选课成功,写入数据库

score.objects.create(cno_id=cno,sno_id=sno)

result = 'True'

return JsonResponse({'result': result})

courseinfo = course.objects.all()

return render_to_response('selcourse.html',locals())

JS代码返回的显示内容适度修改:

function addcourse(cno) {

$.post('/selcourse/', {

'cno':cno,

}, function (res) {

if(res.result=='True'){

alert("选课成功!");

window.location.reload();

}else{

alert(res.result);

window.location.reload();

}

}, 'json')

}

最终效果如下,重复选课提示已选,选修超过2门课程提示超过最大数量,选课成功提示成功。

2.2已选课程删除

同样删除按钮需要使用js向后端传输课程号,html按钮绑定delcourse的js函数,后台业务逻辑函数调用ORM的delete命令进行删除。

JS函数编辑:我们还是采用同样的.post向后台推送数据。

function delcourse(cno) {

$.post('/delcourse/', {

'cno':cno,

}, function (res) {

if(res.result=='True'){

alert("删除成功!");

window.location.reload();

}else{

alert(res.result);

window.location.reload();

}

}, 'json')

}

编辑views.py业务逻辑:单独增加一个删除函数。

def delcourse(request):

if request.method == 'POST' and request.POST:

cno = request.POST['cno']

username = request.session['username']

user = student.objects.get(username=username)

sno = user.sno

# 判断当前要删除的课程是否已选择

selected = score.objects.filter(cno_id=cno,sno_id=sno)

if selected:

score.objects.filter(cno_id=cno,sno_id=sno).delete()

result = 'True'

return JsonResponse({'result': result})

else:

#课程未选择,返回错误

result = '课程未选修,无法删除!'

return JsonResponse({'result': result})

views里面增加了函数,urls记得也要注册路由。

urlpatterns = [

......

url(r'^delcourse/', delcourse),

]

最后前端selcourse.html页面绑定到删除按钮:

最终效果如下:

3、已选课程展示

还是利用magicbox选择一个面板,拷贝代码,然后利旧一下stuinfo里面的

这里的难点有一个关联查询,因为course只有课程内容,没有授课老师,需要通过tno进行跨表连接,而student与course也没有直接联系,需要通过score中间表来进行连接,因此需要进行多表的跨表查询。

(现实生产环境的数据库表与字段比这里的数量要多得多,因此,能够达到目标查询要求的SQL语句的编写,也是数据库开发岗位日常工作的一部分。)

前端页面:stuinfo.html原来

后面继续增加面板与表格。

已选课程

课程ID

课程名称

学分

上课时间

上课地点

授课老师

{% for j in selcourse %}

{{ j.score__cno }}

{{ j.score__cno__cname }}

{{ j.score__cno__ccredit }}

{{ j.score__cno__ctime }}

{{ j.score__cno__cplace}}

{{ j.score__cno__tno_id__tname }}

{% endfor %}

业务逻辑:

def stuinfo(request):

username = request.session['username']

userinfo = student.objects.filter(username=username)

selcourse = student.objects.filter(username=username).values('score__cno','score__cno__cname','score__cno__ccredit',

'score__cno__ctime','score__cno__cplace','score__cno__tno_id__tname')

print (selcourse)

return render_to_response('stuinfo.html',locals())

以上述为例,关联查询,首先找student表进行查询,然后与student表直接关联的表格是score表,所以后面values首先写score,然后双下划线可以直接引用score表里面的字段cno。然后通过cno可以关联到course里面的字段吗,再双下划线引用,通过course里面的tno_id字段又可以关联到teacher表,最后引用teacher表字段。

最终刷新页面效果如下:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值