一、功能介绍
这是一个基于前端页面js代码的动态效果和后端对数据库数据更新的操作,主要实现的是会议室的预定功能,当员工进入预定页面后可以看到某天的某个会议室的某个时段是否被预定,当没被预定的情况下,就可以预定会议室,这相当于对于会议室这种共享资产的合理化分配,快速便捷的完成会议室的预定。前端页面时长这样的。
从上图中,可以清晰的看出那些人预定那些房间。我们要实现的功能如下:
1,当选择一个时间,然后点击提交按钮,就会发送一个基于form表单的post请求,会把时间发过去然后,返回的页面就是刚才选择日期的会议室预定情况
2,点击空白小格子时,颜色会变浅绿,
3,点击被预定的小格子时,当名字是自己的名字时,会使颜色消失,变成白色小格子,然后把房间号和时间段放入删除列表;当点击的名字不是自己时,会弹出警告框,不能对其进行操作
4,点击保存按钮时,会把所有的浅绿的小格子的房间号和时间段放入添加列表;然后发送ajax请求,把添加列表和删除列表发送到后端处理
5,后端拿到数据,先对删除列表,把要删除的删除;然后再处理添加列表,把该添加的添加上
二、代码
1,创建模型
class UserInfo(models.Model): #这是user表
pass
class House(models.Model): #这是房间表
'''会议室表'''
name=models.CharField(max_length=5)
size=models.CharField(max_length=5)
def __str__(self):
return self.name
times=((1, '09:00-10:00'), (2, '10:00-11:00'), (3, '11:00-12:00'), (4, '12:00-13:00'),
(5, '13:00-14:00'), (6, '14:00-15:00'), (7, '15:00-16:00'), (8, '16:00-17:00'),
(9, '17:00-18:00'), (10, '18:00-19:00'), (11, '19:00-20:00'),(12, '20:00-21:00'))
class Order(models.Model): #这是会议室预定记录表
'''会议室预定记录表'''
date=models.DateField()
user=models.ForeignKey(to='UserInfo',on_delete=models.CASCADE)
house=models.ForeignKey(to='House',on_delete=models.CASCADE)
time = models.IntegerField(choices=times)
class Meta:
unique_together = ("date", "house", 'time') #这是联合唯一,
2,前端代码
{% extends 'base.html' %}
{% block css %}
<style>
.outer{
width: 100%;
height: 40px;
background-color: #337ab7;
color: white;
line-height: 40px;
}
.left{
float: left;
margin-top: 10px;
margin-left: 10px;
color: black;
height: 20px;
}
#title{
float: right;
margin-right: 500px;
font-size: 20px;
}
#date{
float: left;
}
</style>
{% endblock %}
{% block content %}
<div class="container">
<div class="outer">
<div id="date"> #这是日期
<form action="/houseorder/" method="post">
{% csrf_token %}
<div>
<input type="submit" style="color: black;height: 20px;margin-top: 10px;line-height: 20px">
<input type="date" name="time" class="left" value="{{ date }}">
</div>
</form>
</div>
<div id="title">会议室预定表</div>
</div>
<table class="table table-bordered">
<thead>
<tr>
<th>会议室</th>
{% for choice in choices %} #这是循环生产时间的信息,也就是表头
<th>{{ choice.1 }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{{ data }} #所有的表体数据都是由后端构造的
</tbody>
</table>
<button class="btn btn-info tijiao">保存</button>
</div>
{% endblock %}
{% block script %}
<script>
var add_dic={};
var del_dic={};
//给每个nn类的标签绑定点击事件
$('.nn').click(function () {
var text=$(this).text();
var user=$('.user').attr('id');
console.log(user);
var num=$(this).children('span').first().attr('class');
var name=$(this).parent().attr('class');
//已经被别人选中的
if ($(this).hasClass('warning')){
alert('别人已经选定')
}
//被自己选中的
else if ($(this).hasClass('danger')){
$(this).removeClass('danger');
$(this).children('span').text('');
if (del_dic[name]){
del_dic[name].push(num)}
else {del_dic[name]=[num]}
}
//刚才被点中的,再次点击,取消颜色
else if($(this).hasClass('success')){
$(this).removeClass('success');
}
//没被选中的,点击变颜色
else {
$(this).addClass('success');
}
});
//保存的点击事件
$('.tijiao').click(function () {
//循环所有的td标签,然后把拥有success类的标签的值放入add_dic
$('td').each(function () {
var num=$(this).children('span').first().attr('class');
var name=$(this).parent().attr('class');
if($(this).hasClass('success')){
if (add_dic[name]){
add_dic[name].push(num)}
else {add_dic[name]=[num]}
}});
//把add_dic,not_add_dic加入一个列表中,最后把当前选择的日期也放进去
var date=$('.left').first().val();
//用ajax请求,把列表发送到后端
$.ajax({
url:'',
type:'post',
data: {'add_dic':JSON.stringify(add_dic),'del_dic':JSON.stringify(del_dic),'date':JSON.stringify(date),'csrfmiddlewaretoken':$('[name="csrfmiddlewaretoken"]').val()},
success: function (res) {
console.log(res);
location.href='/houseorder/?time='+res
}
})
})
</script>
{% endblock %}
3,后端代码
def houseorder(request):
date = request.GET.get('time')
now = time.strftime('%Y-%m-%d', time.localtime(time.time()))
if request.is_ajax(): #这是对ajax请求的处理
add_dic = json.loads(request.POST.get('add_dic'))
del_dic = json.loads(request.POST.get('del_dic'))
date = json.loads(request.POST.get('date'))
date =date or now
if del_dic: #拿到要删除的字典,然后删除
for key, value in del_dic.items():
for ele in value:
Order.objects.filter(date=date, user_id=request.user.id, house_id=int(key),
time=int(ele)).delete()
if add_dic: #这是拿到添加的字典,然后添加
for key, value in add_dic.items():
for i in value:
Order.objects.create(date=date, user_id=request.user.id, house_id=int(key), time=int(i))
return HttpResponse(date)
#点击日历提交的post请求
if request.method == 'POST':
date = request.POST.get('time')
这是构建页面需要的数据,比如说表体。。。
date=date or now
username = request.user.name
orders = Order.objects.filter(date=date)
houses = House.objects.all()
choices = times
data_list = []
for house in houses: #这就是构建表体数据
data_list.append(mark_safe('<tr class="%s"><td>%s(%s)</td>' % (house.id, house.name, house.size)))
for choice in choices:
for order in orders:
if order.house.id == house.id and choice[0] == order.time:
if username==order.user.name:
tt = mark_safe('<td class="nn danger"><span class="%s">%s</span></td>' % (choice[0], order.user.name))
break
else:
tt = mark_safe('<td class="nn warning"><span class="%s">%s</span></td>' % (choice[0], order.user.name))
break
else:
tt =mark_safe( '<td class="nn"><span class="%s"></span></td>' % choice[0])
data_list.append(tt)
data_list.append('</tr>')
data = mark_safe(''.join(data_list))
return render(request, 'houseorder.html', locals())
对于预定类的功能都可以与此雷同,所有就可以用同样思路完成。