django - meeting project说明

web

  • views.py
import json
import datetime
from django.shortcuts import render, HttpResponse, redirect
from django.http import JsonResponse
from . import models
from django.forms import Form
from django.forms import fields
from django.forms import widgets
from django.db.models import Q
from django.db.utils import IntegrityError


class LoginForm(Form):
    name = fields.CharField(
        required=True,
        error_messages={
    
    'required': '用户名不能为空'},
        widget=widgets.TextInput(attrs={
    
    'class': 'form-control', 'placeholder': '用户名', 'id': 'name'})
    )
    password = fields.CharField(
        required=True,
        error_messages={
    
    'required': '密码不能为空'},
        widget=widgets.PasswordInput(attrs={
    
    'class': 'form-control', 'placeholder': '密码', 'id': 'password'})
    )
    rmb = fields.BooleanField(required=False, widget=widgets.CheckboxInput(attrs={
    
    'value': 1}))


def md5(val):
    import hashlib
    m = hashlib.md5()
    m.update(val.encode('utf-8'))
    return m.hexdigest()


def auth(func):
    def inner(request, *args, **kwargs):
        user_info = request.session.get('user_info')
        if not user_info:
            return redirect('/login/')
        return func(request, *args, **kwargs)

    return inner


def auth_json(func):
    def inner(request, *args, **kwargs):
        user_info = request.session.get('user_info')
        if not user_info:
            return JsonResponse({
    
    'status': False, 'msg': '用户未登录'})
        return func(request, *args, **kwargs)

    return inner


def login(request):
    """
    用户登录
    """
    if request.method == "GET":
        form = LoginForm()
        return render(request, 'login.html', {
    
    'form': form})
    else:
        form = LoginForm(request.POST)
        if form.is_valid():
            rmb = form.cleaned_data.pop('rmb')
            form.cleaned_data['password'] = md5(form.cleaned_data['password'])
            user = models.UserInfo.objects.filter(**form.cleaned_data).first()
            if user:
                request.session['user_info'] = {
    
    'id': user.id, 'name': user.name}
                if rmb:
                    request.session.set_expiry(60 * 60 * 24 * 30)
                return redirect('/index/')
            else:
                form.add_error('password', '密码错误')
                return render(request, 'login.html', {
    
    'form': form})
        else:
            return render(request, 'login.html', {
    
    'form': form})


@auth
def index(request):
    """
    会议室预定首页
    :param request: 
    :return: 
    """
    time_choices = models.Booking.time_choices
    return render(request, 'index.html', {
    
    'time_choices': time_choices})


@auth_json
def booking(request):
    """
    获取会议室预定情况以及预定会议室
    :param request: 
    :param date: 
    :return: 
    """
    ret = {
    
    'code': 1000, 'msg': None, 'data': None}
    current_date = datetime.datetime.now().date()

    if request.method == "GET":
        try:
            fetch_date = request.GET.get('date')
            fetch_date = datetime.datetime.strptime(fetch_date, '%Y-%m-%d').date()
            if fetch_date < current_date:
                raise Exception('查询时间不能是以前的时间')

            booking_list = models.Booking.objects.filter(booking_date=fetch_date).select_related('user',
                                                                                                 'room').order_by(
                'booking_time')

            booking_dict = {
    
    }
            for item in booking_list:
                if item.room_id not in booking_dict:
                    booking_dict[item.room_id] = {
    
    item.booking_time: {
    
    'name': item.user.name, 'id': item.user.id}}
                else:
                    if item.booking_time not in booking_dict[item.room_id]:
                        booking_dict[item.room_id][item.booking_time] = {
    
    'name': item.user.name, 'id': item.user.id}
            """
            {
                room_id:{
                    time_id:{''},
                    time_id:{''},
                    time_id:{''},
                }
            }
            """

            room_list = models.MeetingRoom.objects.all()

            booking_info = []
            for room in room_list:
                temp = [{
    
    'text': room.title, 'attrs': {
    
    'rid': room.id}, 'chosen': False}]
                for choice in models.Booking.time_choices:
                    v = {
    
    'text': '', 'attrs': {
    
    'time-id': choice[0], 'room-id': room.id}, 'chosen': False}
                    if room.id in booking_dict and choice[0] in booking_dict[room.id]:
                        v['text'] = booking_dict[room.id][choice[0]]['name']
                        v['chosen'] = True
                        if booking_dict[room.id][choice[0]]['id'] != request.session['user_info']['id']:
                            v['attrs']['disable'] = 'true'
                    temp.append(v)
                booking_info.append(temp)

            ret['data'] = booking_info
        except Exception as e:
            ret['code'] = 1001
            ret['msg'] = str(e)
        return JsonResponse(ret)
    else:
        try:
            booking_date = request.POST.get('date')
            booking_date = datetime.datetime.strptime(booking_date, '%Y-%m-%d').date()
            if booking_date < current_date:
                raise Exception('查询时间不能是以前的时间')

            booking_info = json.loads(request.POST.get('data'))

            for room_id, time_id_list in booking_info['add'].items():
                if room_id not in booking_info['del']:
                    continue
                for time_id in list(time_id_list):
                    if time_id in booking_info['del'][room_id]:
                        booking_info['del'][room_id].remove(time_id)
                        booking_info['add'][room_id].remove(time_id)

            add_booking_list = []
            for room_id, time_id_list in booking_info['add'].items():
                for time_id in time_id_list:
                    obj = models.Booking(
                        user_id=request.session['user_info']['id'],
                        room_id=room_id,
                        booking_time=time_id,
                        booking_date=booking_date
                    )
                    add_booking_list.append(obj)
            models.Booking.objects.bulk_create(add_booking_list)

            remove_booking = Q()
            for room_id, time_id_list in booking_info['del'].items():
                for time_id in time_id_list:
                    temp = Q()
                    temp.connector = 'AND'
                    temp.children.append(('user_id', request.session['user_info']['id'],))
                    temp.children.append(('booking_date', booking_date,))
                    temp.children.append(('room_id', room_id,))
                    temp.children.append(('booking_time', time_id,))
                    remove_booking.add(temp, 'OR')
            if remove_booking:
                models.Booking.objects.filter(remove_booking).delete()
        except IntegrityError as e:
            ret['code'] = 1011
            ret['msg'] = '会议室已被预定'

        except Exception as e:
            ret['code'] = 1012
            ret['msg'] = '预定失败:%s' % str(e)

    return JsonResponse(ret)
  • models.py
from django.db import models


class UserInfo(models.Model):
    name = models.CharField(verbose_name='用户姓名', max_length=32)
    password = models.CharField(verbose_name='密码', max_length=32)

    def __str__(self):
        return self.name


class MeetingRoom(models.Model):
    title = models.CharField(verbose_name='会议室', max_length=32)

    def __str__(self):
        return self.title


class Booking(models.Model):
    user = models.ForeignKey(to='UserInfo', verbose_name='用户', on_delete = models.CASCADE)

    room = models.ForeignKey(to='MeetingRoom',verbose_name='会议室',  on_delete = models.CASCADE)

    booking_date = models.DateField(verbose_name='预定日期')

    time_choices = (
        (1, '08:00-09:00'),
        (2, '09:00-10:00'),
        (3, '10:00-10:00'),
        (4, '11:00-12:00'),
        (5, '12:00-13:00'),
        (6, '13:00-14:00'),
        (7, '14:00-15:00'),
        (8, '15:00-16:00'),
        (9, '16:00-17:00'),
        (10, '17:00-18:00'),
        (11, '18:00-19:00'),
        (12, '19:00-20:00'),
        (13, '20:00-21:00'),       
    )
    booking_time = models.IntegerField(verbose_name='预定时间段', choices=time_choices)

    class Meta:
        unique_together = (
            ('booking_date', 'booking_time', 'room')
        )
  • admin.py
from django.contrib import admin

# Register your models here.
from web.models import UserInfo,MeetingRoom,Booking


class UserInfoAdmin(admin.ModelAdmin):
    list_display = ('name', 'password')


class MeetingRoomAdmin(admin.ModelAdmin):
    list_display = ['title']


class BookingRoomAdmin(admin.ModelAdmin):
    list_display = ('booking_date', 'booking_time', 'room')


admin.site.register(UserInfo,UserInfoAdmin)
admin.site.register(MeetingRoom,MeetingRoomAdmin)
admin.site.register(Booking,BookingRoomAdmin)

templates

  • index.html
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="{% static 'plugins/bootstrap/css/bootstrap.min.css' %}">
    <link rel="stylesheet" href="{% static 'plugins/datetimepicker/bootstrap-datetimepicker.min.css' %}">
    <style>
        body {
     
     
            font-size: 10px;
        }

        .shade {
     
     
            position: fixed;
            z-index: 1040;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: #999;
            filter: alpha(opacity=50);
            -moz-opacity: 0.5;
            opacity: 0.5;
        }

        .loading {
     
     
            position: fixed;
            z-index: 1050;
            top: 40%;
            left: 50%;
            height: 32px;
            width: 32px;
            margin: 0 0 0 -16px;
            background: url(/static/img/loading.gif);
        }

        table > tbody td {
     
     
            height: 80px;
            width: 80px;
            text-align: center;
        }

        table > tbody td.chosen {
     
     
            background-color: #F0FFF0;
        }

        table > tbody td.selected {
     
     
            background-color: #EEE685;
        }
    </style>
</head>
<body>

<div class="container">

    <h1>会议室预定</h1>
    <div class="clearfix" style="padding: 10px 0;float: right">
        <div style="float: left;color: red" id="errors"></div>
        <div class='input-group' style="width: 230px;float:left;">
            <input type='text' class="form-control" id='datetimepicker11' placeholder="请选择日期"/>
            <span class="input-group-addon">
                <span class="glyphicon glyphicon-calendar">
                </span>
            </span>
        </div>
        <div style="padding: 0 5px;float: left">
            <a id="save" href="#" class="btn btn-primary">保存</a>
        </div>
    </div>

    <table class="table table-bordered">
        <thead>
        <tr>
            <th>会议室</th>
            {% for choice in time_choices %}
                <th>{
   
   { choice.1 }}</th>
            {% endfor %}
        </tr>
        </thead>
        <tbody id="tBody">

        </tbody>
    </table>
</div>


<!-- 遮罩层开始 -->
<div id='shade' class='shade hide'></div>
<!-- 遮罩层结束 -->
<!-- 加载层开始 -->
<div id='loading' class='loading hide'></div>
<!-- 加载层结束 -->


<script src="{% static 'js/jquery-1.12.4.min.js' %}"></script>
<script src="{% static 'js/jquery.cookie.js' %}"></script>
<script src="{% static 'plugins/bootstrap/js/bootstrap.min.js' %}"></script>
<script src="{% static 'plugins/datetimepicker/bootstrap-datetimepicker.min.js' %}"></script>
<script src="{% static 'plugins/datetimepicker/bootstrap-datetimepicker.zh-CN.js' %}"></script>
<script>

    // 对Date的扩展,将 Date 转化为指定格式的String
    // 月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符,
    // 年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字)
    // 例子:
    // (new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423
    // (new Date()).Format("yyyy-M-d h:m:s.S")      ==> 2006-7-2 8:9:4.18
    Date.prototype.Format = 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]) : (("00" + o[k]).substr(("" + o[k]).length)));
        return fmt;
    };
    SELECTED_ROOM = {
     
     del: {
     
     }, add: {
     
     }};
    CHOSEN_DATE = new Date().Format('yyyy-MM-dd');

    $(function () {
     
     
        initDatepicker();
        initBookingInfo(new Date().Format('yyyy-MM-dd'));
        bindTdEvent();
        bindSaveEvent();
    });

    function csrfSafeMethod(method) {
     
     
        // these HTTP methods do not require CSRF protection
        return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
    }
    $.ajaxSetup({
     
     
        beforeSend: function (xhr, settings) {
     
     
            if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
     
     
                xhr.setRequestHeader("X-CSRFToken", $.cookie('csrftoken'));
            }
        }
    });

    function initDatepicker() {
     
     
        $('#datetimepicker11').datetimepicker({
     
     
            minView: "month",
            language: "zh-CN",
            sideBySide: true,
            format: 'yyyy-mm-dd',
            bootcssVer: 3,
            startDate: new Date()
            //autoclose: true,
        }).on('changeDate', changeDate);
    }

    function changeDate(ev) {
     
     
        CHOSEN_DATE = ev.date.Format('yyyy-MM-dd');
        initBookingInfo(CHOSEN_DATE);

    }

    function initBookingInfo(date) {
     
     
        SELECTED_ROOM = {
     
     del: {
     
     }, add: {
     
     }};

        $('#shade,#loading').removeClass('hide');
        $.ajax({
     
     
            url: '/booking/',
            type: 'get',
            data: {
     
     date: date},
            dataType: 'JSON',
            success: function (arg) {
     
     
                $('#shade,#loading').addClass('hide');
                if (arg.code === 1000) {
     
     
                    $('#tBody').empty();
                    $.each(arg.data, function (i, item) {
     
     
                        var tr = document.createElement('tr');
                        $.each(item, function (j, row) {
     
     
                            var td = document.createElement('td');
                            $(td).text(row.text);

                            $.each(row.attrs, function (k, v) {
     
     
                                $(td).attr(k, v);
                            });
                            if (row.chosen) {
     
     
                                $(td).addClass('chosen');
                            }
                            $(tr).append(td)
                        });
                        $('#tBody').append(tr);
                    })
                } else {
     
     
                    alert(arg.msg);
                }
            },
            error: function () {
     
     
                $('#shade,#loading').addClass('hide');
                alert('请求异常');
            }
        })
    }

    /*
     绑定预定会议室事件
     */
    function bindTdEvent() {
     
     
        $('#tBody').on('click', 'td[time-id][disable!="true"]', function () {
     
     

            var roomId = $(this).attr('room-id');
            var timeId = $(this).attr('time-id');

            //var item = {'roomId': $(this).attr('room-id'), 'timeId': $(this).attr('time-id')};

            if ($(this).hasClass('chosen')) {
     
     
                $(this).removeClass('chosen').empty();
                // 取消原来的预定
                //SELECTED_ROOM['del'].push(item);
                if (SELECTED_ROOM.del[roomId]) {
     
     
                    SELECTED_ROOM.del[roomId].push(timeId);
                } else {
     
     
                    SELECTED_ROOM.del[roomId] = [timeId];
                }

            } else if ($(this).hasClass('selected')) {
     
     
                $(this).removeClass('selected');
                // 取消选择
                var timeIndex = SELECTED_ROOM.add[roomId].indexOf(timeId);
                if (timeIndex !== -1) {
     
     
                    SELECTED_ROOM.add[roomId].splice(timeIndex, 1);
                }
            } else {
     
     
                $(this).addClass('selected');
                // 选择
                if (SELECTED_ROOM.add[roomId]) {
     
     
                    SELECTED_ROOM.add[roomId].push(timeId);
                } else {
     
     
                    SELECTED_ROOM.add[roomId] = [timeId];
                }
            }
        })
    }

    /*
     保存按钮
     */
    function bindSaveEvent() {
     
     
        $('#errors').text('');

        $('#save').click(function () {
     
     
            $('#shade,#loading').removeClass('hide');
            $.ajax({
     
     
                url: '/booking/',
                type: 'POST',
                data: {
     
     date: CHOSEN_DATE, data: JSON.stringify(SELECTED_ROOM)},
                dataType: 'JSON',
                success: function (arg) {
     
     
                    $('#shade,#loading').addClass('hide');
                    if (arg.code === 1000) {
     
     
                        initBookingInfo(CHOSEN_DATE);
                    } else {
     
     
                        $('#errors').text(arg.msg);
                    }
                }
            });
        });

    }


</script>
</body>
</html>
  • login.html
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="{% static 'plugins/bootstrap/css/bootstrap.min.css' %}">
</head>
<body>

<div style="width: 500px;margin: 50px auto;">
    <form class="form-horizontal" method="post" novalidate>
        {% csrf_token %}
        <div class="form-group">
            <label for="name" class="col-sm-2 control-label">用户名:</label>
            <div class="col-sm-10">
                {
   
   { form.name }}
                {
   
   { form.errors.name.0 }}
            </div>
        </div>
        <div class="form-group">
            <label for="password" class="col-sm-2 control-label">密码:</label>
            <div class="col-sm-10">
                {
   
   { form.password }}
                {
   
   { form.errors.password.0 }}
            </div>
        </div>
        <div class="form-group">
            <div class="col-sm-offset-2 col-sm-10">
                <div class="checkbox">
                    <label>
                       {
   
   { form.rmb }} 一周免登录
                    </label>
                </div>
            </div>
        </div>
        <div class="form-group">
            <div class="col-sm-offset-2 col-sm-10">
                <button type="submit" class="btn btn-primary">登录</button>
            </div>
        </div>
    </form>
    <div>
        <p>用户名:周杰伦  密码:123</p>
        <p>用户名:吴彦祖  密码:123</p>
    </div>
</div>
</body>
</html>

猜你喜欢

转载自blog.csdn.net/m0_46629123/article/details/114130164
今日推荐