2018-10-14 17:12:32

越努力,越幸运.永远不要高估自己!

网上修改一下博客网站样式,做个仿qq空间的!

放上github连接 :https://github.com/TrueNewBee/pythonDemo/blob/master/%E9%A2%84%E5%AE%9A%E4%BC%9A%E8%AE%AE%E5%AE%A4.rar
整体实现不难:

预定会议室功能实现:
1.登入后 /login/ 后 可以看到所有人的预订
2.绿色为当前登录人的预订
3.点击某单元删除和添加预订,如果选择了重复则有提示
4.通过了Ajax请求,去掉了crsf跨站请求伪造

放上源码:

views.py

from django.shortcuts import render, redirect, HttpResponse
from django.contrib import auth
from .models import *
from django.db.models import Q
import json
import datetime
# 超级用户 root root1234
# zhen zhen1234 def login(request):
if request.method == "POST":
user = request.POST.get("user")
pwd = request.POST.get("pwd")
user = auth.authenticate(username=user, password=pwd)
if user:
auth.login(request, user) # request.user
return redirect("/index/") return render(request, "login.html") def index(request):
# 获取当前日期
date = datetime.datetime.now().date()
# 查看特定日期下的book
book_date = request.GET.get("book_date",date)
time_choices = Book.time_choices
room_list = Room.objects.all()
# 找到该日期下的预订的会议室
book_list = Book.objects.filter(date=book_date)
htmls = ""
for room in room_list:
htmls += "<tr><td>{}({})</td>".format(room.caption,room.num)
for time_choice in time_choices:
book = None
flag = False
for book in book_list:
# 判断这个单元格的纵横坐标是否存在
if book.room.pk == room.pk and book.time_id == time_choice[0]:
# 味这个单元格已被预定
flag = True
break if flag:
# 根据flog的变化 加上特定的class 在前端通过class来添加css
if request.user.pk == book.user.pk:
htmls += "<td class='active item' room_id={} time_id={}>{}</td>".format(room.pk, time_choice[0], book.user.username)
else:
htmls += "<td class='another_active item' room_id={} time_id={}>{}</td>".format(room.pk, time_choice[0], book.user.username)
else:
htmls+="<td room_id={} time_id={} class='item'></td>".format(room.pk,time_choice[0])
htmls += "</tr>"
return render(request, "index.html", locals()) def book(request):
print(request.POST)
post_data = json.loads(request.POST.get("post_data")) # {"ADD":{"1":["5"],"2":["5","6"]},"DEL":{"3":["9","10"]}}
choose_date = request.POST.get("choose_date") res = {"state": True, "msg" : None}
try:
# 添加预定
# post_data["ADD"] : {"1":["5"],"2":["5","6"]}
book_list = []
for room_id, time_id_list in post_data["ADD"].items():
for time_id in time_id_list:
book_obj = Book(user=request.user, room_id=room_id, time_id=time_id, date=choose_date)
book_list.append(book_obj)
Book.objects.bulk_create(book_list)
# 删除预定
# post_data["DEL"]: {"2":["2","3"]}
remove_book = Q()
for room_id, time_id_list in post_data["DEL"].items():
temp = Q()
for time_id in time_id_list:
temp.children.append(("room_id", room_id))
temp.children.append(("time_id", time_id))
temp.children.append(("user_id", request.user.pk))
temp.children.append(("date", choose_date))
remove_book.add(temp, "OR")
if remove_book:
Book.objects.filter(remove_book).delete()
except Exception as e:
res["state"] = False
res["msg"] = str(e)
return HttpResponse(json.dumps(res))

index.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css">
<script src="/static/js/jquery-1.12.4.min.js"></script> <script src="/static/datetimepicker/bootstrap-datetimepicker.min.js"></script>
<script src="/static/datetimepicker//bootstrap-datetimepicker.zh-CN.js"></script> <style>
.active{
background-color: green!important;
color: white;
}
.another_active{
background-color: #2b669a;
color: white;
} .td_active{
background-color: lightblue;
color: white;
}
</style>
</head>
<body> <h3>会议室预定</h3> <div class="calender pull-right">
<div class='input-group' style="width: 230px;">
<input type='text' class="form-control" id='datetimepicker11' placeholder="请选择日期"/>
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar">
</span>
</span> </div>
</div> <table class="table table-bordered table-striped"> <thead>
<tr>
<th>会议室/时间</th>
{% for time_choice in time_choices %}
<th>{{ time_choice.1 }}</th>
{% endfor %} </tr>
</thead> <tbody>
{{ htmls|safe }}
</tbody> </table>
<button class="btn btn-success pull-right keep">保存</button> <script >
// js 必会的 字符串 数组 object { }
// 日期格式化方法
Date.prototype.yuan = function (fmt) { //author: meizz
var o = {
"M+": this.getMonth() + 1, //月份
"d+": this.getDate(), //日
"h+": this.getHours(), //小时
"m+": this.getMinutes(), //分
"s+": this.getSeconds(), //秒
"q+": Math.floor((this.getMonth() + 3) / 3), //季度
"S": this.getMilliseconds() //毫秒
};
if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var k in o)
if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("" + o[k]).substr(("" + o[k]).length)));
return fmt;
}; var POST_DATA={
"ADD":{},
"DEL":{}, }; // 为td绑定单击事件 function BindTd() {
$(".item").click(function () { var room_id=$(this).attr("room_id");
var time_id=$(this).attr("time_id"); // 取消预定
if($(this).hasClass("active")){
$(this).removeClass("active").empty(); if(POST_DATA.DEL[room_id]){
POST_DATA.DEL[room_id].push(time_id)
}else {
POST_DATA.DEL[room_id]=[time_id,]
}
}
// 临时取消预定
else if ($(this).hasClass("td_active")){
$(this).removeClass("td_active");
POST_DATA.ADD[room_id].pop() }
else{ // 添加预定
$(this).addClass("td_active");
if(POST_DATA.ADD[room_id]){
POST_DATA.ADD[room_id].push(time_id)
}else {
POST_DATA.ADD[room_id]=[time_id,]
} } })
} BindTd(); // 日期 if (location.search.slice(11)){
CHOOSE_DATE = location.search.slice(11)
}
else {
CHOOSE_DATE = new Date().yuan('yyyy-MM-dd');
} // 发送ajax $(".keep").click(function () { $.ajax({
url:"/book/",
type:"POST",
data:{
choose_date:CHOOSE_DATE,
post_data:JSON.stringify(POST_DATA),
},
dataType:"json",
success:function (data) {
console.log(data)
if(data.state){
// 预定成功
location.href=""
}else {
alert("预定的房间已经被预定")
location.href=""
} } })
}); // 日历插件
$('#datetimepicker11').datetimepicker({
minView: "month",
language: "zh-CN",
sideBySide: true,
format: 'yyyy-mm-dd',
startDate: new Date(),
bootcssVer: 3,
autoclose: true,
}).on('changeDate', book_query);
function book_query(e) {
CHOOSE_DATE=e.date.yuan("yyyy-MM-dd");
location.href="/index/?book_date="+CHOOSE_DATE;
} </script>
</body>
</html>

models.py

from django.db import models
from django.contrib.auth.models import AbstractUser # 需要在settings配置 AUTH_USER_MODEL = "app01.UserInfo"
class UserInfo(AbstractUser):
tel = models.CharField(max_length=32) class Room(models.Model):
"""
会议室表
"""
caption = models.CharField(max_length=32)
num = models.IntegerField() # 容纳人数 def __str__(self):
return self.caption class Book(models.Model):
"""
会议室预定信息 """
user = models.ForeignKey('UserInfo')
room = models.ForeignKey('Room')
date = models.DateField()
time_choices = (
(1, '8:00'),
(2, '9:00'),
(3, '10:00'),
(4, '11:00'),
(5, '12:00'),
(6, '13:00'),
(7, '14:00'),
(8, '15:00'),
(9, '16:00'),
(10, '17:00'),
(11, '18:00'),
(12, '19:00'),
(13, '20:00'),
)
# 会渲染成下拉菜单
time_id = models.IntegerField(choices=time_choices) # 联合唯一
class Meta:
unique_together = (
('room','date','time_id'),
) def __str__(self):
return str(self.user)+"预定了"+str(self.room)

urls.py

"""MRBS URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^login/', views.login),
url(r'^index/', views.index),
url(r'^book/', views.book),
]

贴上笔记:

POST:

浏览器-------------------->server
"请求首行\r\nContent-Type:url_encode\r\n\r\na=1&b=2"
"请求首行\r\nContent-Type:application/json\r\n\r\n'{"a":1,"b":2}'" 在django的wsgi的request中:
request.body:元数据'{"a":1,"b":2}' if 请求头中的Content-Type==url_encode:
request.POST=解码a=1&b=2 Q: 方式1:
q=Q()
q.connection="or"
q.children.append("pk",1)
q.children.append("user_id",1)
q.children.append("room_id",1) Book.objects.filter(q) 方式2:
Book.objects.filter(Q(pk=1)|Q(user_id=1)|Q(room_id=1))

10.14 预订会议室的小Demo的更多相关文章

  1. Android -- 自定义View小Demo,动态画圆(一)

    1,转载:(http://blog.csdn.NET/lmj623565791/article/details/24500107),现在如下图的效果: 由上面的效果图可以看到其实是一个在一个圆上换不同 ...

  2. 模仿京东顶部搜索条效果制作的一个小demo

    最近模仿京东顶部搜索条效果制作的一个小demo,特贴到这里,今后如果有用到可以参考一下,代码如下 #define kScreenWidth [UIScreen mainScreen].bounds.s ...

  3. js特效 15个小demo

    js特效和15个小demo 代码如下:images文件夹未上传 1.图片切换: <!DOCTYPE html> <html> <head> <title> ...

  4. dubbo泛化调用 小demo

    前两天刚好有个同事来问是否用过 dubbo泛化 调用,不需要通过指定配置.第一次听到的时候,还是有点懵,但觉得有意思,可以学点东西. 立马百度了,找了demo,这篇比较容易上手(http://www. ...

  5. Android学习小Demo一个显示行线的自定义EditText

    今天在处理一个EditText的时候,想着把EditText做成像一本作业本上的纸一样,每一行都可以由线条隔开,具体效果如下: 1)最开始的思路 一开始的想法是很简单的,找出每一行的高度,然后一行一行 ...

  6. React问答小demo

    在学习react初期,看了一些视频和资料,react基础知识差不多学完,跟着网上的一个教程,做了一个小型的问答demo. 需求看图说: 1.点击"添加"按钮,显示问题输入表单,再次 ...

  7. 一周一个小demo — 前端后台的交互实例

    这一周呢,本K在大神的指导下,完成了一个利用ajax与php文件上传处理相结合的一个留言板功能的小实例,下面就让本K来带大家瞅瞅如何实现这一种功能. 一.界面概览 首先我们来看一下这个小demo的具体 ...

  8. 基于BaseAdapter的Listview小Demo

    ListView是android开发中比较常用的控件, 其中适配器模式可以选择: ArrayAdapter:简单易用,通常用于将数组或者List集合的读个包值封装成多个列表项 SimpleAdapte ...

  9. python turtle库的几个小demo

    一.先上图 一个同切圆和五角星 上代码 import turtle #同切圆 turtle.pensize(2) turtle.circle(10) turtle.circle(40) turtle. ...

随机推荐

  1. 如何Python下载大文件?

    我想用python脚本下载很多文件,但是经常就有那么几个出错,写了个error handling,跳了过去,但是把出错的链接保存了一下. 转过天来,研究了一下出的什么错. 一个报错如下: PS C:\ ...

  2. 权威公布:彻底搞清楚哪些笔记本和台式机主板能够支持42mm SATA M.2 NGFF(2242)接口的固态硬盘!!!

    在京东,天猫上搜寻半天.致电联想客服以及各个固态盘的店小二.都搞不清楚兼容性问题.并且联想客服的回答明显错误,官网描写叙述也错误,客服project师也含糊不清说:要拆机试一试才知道是否兼容. 我就不 ...

  3. jstl 格式化

    一:JSTL格式化标签又称为I18N标签库,主要用来编写国际化的WEB应用,使用此功能可以对一个特定的语言请求做出合适的处理.例如:中国内地用户将显示简体中文,台湾地区则显示繁体中文,使用I18N格式 ...

  4. 转发:查看centos中的用户和用户组

    1.用户列表文件:/etc/passwd/ 2.用户组列表文件:/etc/group 3.查看系统中有哪些用户: cut -d : -f 1 /etc/passwd 4.查看可以登录系统的用户: ca ...

  5. arcgismanager登陆信息不对

    arcgis版本:arcgis10 安装arcgis server后(java版的win764位系统),发现arcgis管理器登陆界面(http://localhost:8099/arcgismana ...

  6. openssl - 数字证书的编程解析

    原文链接: http://www.cangfengzhe.com/wangluoanquan/37.html 这篇文章主要介绍PKI公钥体系中非常核心元素——数字证书的编程解析.在SSL,SET等安全 ...

  7. Linux系统命令缩写

    命令缩写:(转) ls:list(列出目录内容) cd:Change Directory(改变目录) su:switch user 切换用户 rpm:redhat package manager 红帽 ...

  8. 最好的Python机器学习库

    参考链接:http://www.csdn.net/article/2015-12-10/2826435

  9. Socket网络编程--聊天程序(8)

    上一节已经完成了对用户的身份验证了,既然有了验证,那么接下来就能对不同的客户端进行区分了,所以这一节讲实现私聊功能.就是通过服务器对客户端的数据进行转发到特定的用户上, 实现私聊功能的聊天程序 实现的 ...

  10. ajax请求中的6个全局事件

    //事件触发顺序ajaxStart,ajaxSend,ajaxSuccess或ajaxError,ajaxComplete,ajaxStop $(document).ajaxStart(functio ...