• CRM、用户管理权限


    CRM目录结构

    service/stark.py
    class Pagination(object):
        def __init__(self, current_page, all_count,params, per_page_num=10, pager_count=11):
            """
            封装分页相关数据
            :param current_page: 当前页
            :param all_count:    数据库中的数据总条数
            :param per_page_num: 每页显示的数据条数
            :param pager_count:  最多显示的页码个数
    
            用法:
            queryset = model.objects.all()
            page_obj = Pagination(current_page,all_count)
            page_data = queryset[page_obj.start:page_obj.end]
            获取数据用page_data而不再使用原始的queryset
            获取前端分页样式用page_obj.page_html
            """
            try:
                current_page = int(current_page)
            except Exception as e:
                current_page = 1
    
            if current_page < 1:
                current_page = 1
    
            self.current_page = current_page
    
            self.all_count = all_count
            self.per_page_num = per_page_num
    
            # 总页码
            all_pager, tmp = divmod(all_count, per_page_num)
            if tmp:
                all_pager += 1
            self.all_pager = all_pager
    
            self.pager_count = pager_count
            self.pager_count_half = int((pager_count - 1) / 2)
    
            import copy
            self.params = copy.deepcopy(params)
    
        @property
        def start(self):
            return (self.current_page - 1) * self.per_page_num
    
        @property
        def end(self):
            return self.current_page * self.per_page_num
    
        def page_html(self):
            # 如果总页码 < 11个:
            if self.all_pager <= self.pager_count:
                pager_start = 1
                pager_end = self.all_pager + 1
            # 总页码  > 11
            else:
                # 当前页如果<=页面上最多显示11/2个页码
                if self.current_page <= self.pager_count_half:
                    pager_start = 1
                    pager_end = self.pager_count + 1
    
                # 当前页大于5
                else:
                    # 页码翻到最后
                    if (self.current_page + self.pager_count_half) > self.all_pager:
                        pager_end = self.all_pager + 1
                        pager_start = self.all_pager - self.pager_count + 1
                    else:
                        pager_start = self.current_page - self.pager_count_half
                        pager_end = self.current_page + self.pager_count_half + 1
    
            page_html_list = []
            # 添加前面的nav和ul标签
            page_html_list.append('''
                        <nav aria-label='Page navigation>'
                        <ul class='pagination'>
                    ''')
            first_page = '<li><a href="?page=%s">首页</a></li>' % (1)
            page_html_list.append(first_page)
    
            if self.current_page <= 1:
                prev_page = '<li class="disabled"><a href="#">上一页</a></li>'
            else:
                prev_page = '<li><a href="?page=%s">上一页</a></li>' % (self.current_page - 1,)
    
            page_html_list.append(prev_page)
    
            res = self.params
            for i in range(pager_start, pager_end):
                res['page'] = i
                if i == self.current_page:
                    temp = '<li class="active"><a href="?%s">%s</a></li>' % (res.urlencode(), i,)
                else:
                    temp = '<li><a href="?%s">%s</a></li>' % (res.urlencode(), i,)
                page_html_list.append(temp)
    
            if self.current_page >= self.all_pager:
                next_page = '<li class="disabled"><a href="#">下一页</a></li>'
            else:
                next_page = '<li><a href="?page=%s">下一页</a></li>' % (self.current_page + 1,)
            page_html_list.append(next_page)
    
            last_page = '<li><a href="?page=%s">尾页</a></li>' % (self.all_pager,)
            page_html_list.append(last_page)
            # 尾部添加标签
            page_html_list.append('''
                                               </nav>
                                               </ul>
                                           ''')
            return ''.join(page_html_list)
    utils/my_page

    templates/stark

    {% extends 'stark/base.html' %}
    
    {% block css %}
        <link rel="stylesheet" href="/static/css/common.css">
    {% endblock %}
    {% block content %}
    
        <h3>添加数据</h3>
        <form action="" method="post">
            {% csrf_token %}
            {% for foo in model_form_obj %}
            <div class="form-inline fa-plus">
                <p>{{ foo.label }}{{ foo }}</p>
                {% if foo.is_pop %}
                <span class="plus" onclick="openWindow('{{ foo.url }}')">+</span>
                {% endif %}
            </div>
            {% endfor %}
            <input type="submit" class="btn btn-info pull-right">
        </form>
    
        <script>
            function openWindow(url) {
                window.open(url,'','width=800px,height=400px');
            }
    
            function add_options(pop_back_id,pk,text) {
                var opEle = document.createElement('option');
                opEle.value = pk;
                opEle.innerText = text;
                opEle.selected = 'selected';
                var seEle = document.getElementById(pop_back_id);
                seEle.appendChild(opEle);
            }
        </script>
    
    {% endblock %}
    add.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
        <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
        <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
        <style>
            .table {
                margin-top: 10px;
            }
            .active {
                color: red;
            }
            .fa-plus {
                position: relative;
            }
            .plus {
                font-size: 24px;
                color: #336699;
                position: absolute;
                right: -31px;
                top: 19px;
            }
        </style>
        {% block css %}
    
        {% endblock %}
    </head>
    <body>
    {#  导航条开始 #}
    <nav class="navbar navbar-default">
      <div class="container-fluid">
        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header">
          <a class="navbar-brand" href="#">CRM</a>
        </div>
        <!-- Collect the nav links, forms, and other content for toggling -->
        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
          <ul class="nav navbar-nav navbar-right">
            <li>{% if request.session.user %}
                <a href="">{{ request.session.user }}</a>
                {% else %}
                <a href="/login/">登陆</a>
            {% endif %}</li>
            <li class="dropdown">
              <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
              <ul class="dropdown-menu">
                <li><a href="#">Action</a></li>
                <li><a href="#">Another action</a></li>
                <li><a href="#">Something else here</a></li>
                <li role="separator" class="divider"></li>
                <li><a href="/logout/">注销</a></li>
              </ul>
            </li>
          </ul>
        </div><!-- /.navbar-collapse -->
      </div><!-- /.container-fluid -->
    </nav>
    {#  导航条结束 #}
    
    
    
    <div class="container">
        <div class="row">
            <div class="col-md-3">
                <div class="menu">
                    <p><a href="/index">首页</a></p>
                    {% for foo in request.session.permission_menu_list %}
                    <p><a href="{{ foo.url }}">{{ foo.title }}</a></p>
                    {% endfor %}
                </div>
            </div>
            <div class="col-md-9">
                {% block content %}
    
                {% endblock %}
            </div>
        </div>
    </div>
    
    
    </body>
    </html>
    base.html
    {% extends 'stark/base.html' %}
    
    {% block css %}
        <link rel="stylesheet" href="/static/css/common.css">
    {% endblock %}
    {% block content %}
    
        <h3>编辑数据</h3>
        <form action="" method="post">
            {% csrf_token %}
            {% for foo in model_form_obj %}
            <p>{{ foo.label }}{{ foo }}</p>
            {% endfor %}
            <input type="submit" class="btn btn-success pull-right">
        </form>
    
    
    
    
    
    {% endblock %}
    edit.html
    {% extends 'stark/base.html' %}
    
    
    {% block content %}
    <div class="jumbotron">
      <h1>Hello, world!</h1>
      <p>...</p>
      <p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a></p>
    </div>
    {% endblock %}
    index
    {% extends 'stark/base.html' %}
    
    {% block css %}
        <script src="/static/js/check.js"></script>
    {% endblock %}
    
    {% block content %}
            <h3>查看数据</h3>
            <a href="{{ url }}" class="btn btn-primary">添加数据</a>
            {#    search功能开始#}
            {% if show_obj.config_obj.search_fields %}
                <form class="form-inline pull-right">
                    <div class="form-group">
                        <div class="input-group">
                            <input type="text" class="form-control" id="exampleInputAmount" placeholder="关键字" name="q"
                                   value="{{ show_obj.config_obj.key_word }}">
                        </div>
                    </div>
                    <button type="submit" class="btn btn-danger">Search</button>
                </form>
            {% endif %}
            {#    search功能结束#}
            {#    action功能开始#}
            <form action="" class="form-inline" method="post">
                {% csrf_token %}
                <select class="form-control" name="action">
                    <option value="">-------------------------</option>
                    {% for foo in show_obj.get_action %}
                        <option value="{{ foo.name }}">{{ foo.desc }}</option>
                    {% endfor %}
                </select>
                <input type="submit" value="Go!" class="btn btn-info">
                <table class="table table-bordered table-striped table-hover">
                    <thead>
                    <tr>
                        {% for head in show_obj.get_header %}
                            <th>{{ head }}</th>
                        {% endfor %}
                    </tr>
                    </thead>
                    <tbody>
                    {% for data in show_obj.get_body %}
                        <tr>
                            {% for foo in data %}
                                <td>{{ foo }}</td>
                            {% endfor %}
                        </tr>
                    {% endfor %}
                    </tbody>
                </table>
            </form>
            {{ show_obj.page_obj.page_html|safe }}
    
        {% if show_obj.config_obj.list_filter %}
            <div class="col-md-3">
                <div class="alert-info text-center">FILTER</div>
                {% for foo,data_list in show_obj.get_filter.items %}
                    <div class="panel panel-default">
                        <div class="panel-heading">By {{ foo }}</div>
                        <div class="panel-body">
                            {% for data in data_list %}
                                <p>{{ data }}</p>
                            {% endfor %}
                        </div>
                    </div>
                {% endfor %}
            </div>
        {% endif %}
    
    {% endblock %}
    list.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
    </head>
    <body>
    <script>
        window.opener.add_options('{{ pop_back_id }}','{{ pk }}','{{ text }}');
        window.close();
    
    </script>
    
    </body>
    </html>
    pop.html

    permissionmiddle

    from django.utils.deprecation import MiddlewareMixin
    from django.shortcuts import redirect,HttpResponse
    import re
    
    class PermissionMiddleWare(MiddlewareMixin):
        def process_request(self,request):
            # 当前用户访问路径
            current_path = request.path
            # 用户访问白名单
            white_list = ['/login/','/admin/*']
            for white_permission in white_list:
                res = re.search(white_permission,current_path)
                if res:
                    return None
            # 校验是否登陆
            if not request.session.get('user'):
                return redirect('/login')
            # 获取当前用户访问权限
            permission_list = request.session.get('permission_list')
    
            # 判断是否有权访问
    
            for permission_rex in permission_list:
                permission_rex = '^%s$'%permission_rex
                res = re.search(permission_rex,current_path)
                if res:
                    return None
            return HttpResponse('没有访问权限')
    permission.py

    static/js

    window.onload = function () {
     $('.xxx').change(function () {
         var status = $(this).val();
         var pk = $(this).attr('pk');
         $.ajax({
             url:'/stark/app01/studentstudyrecord/check_work/',
             type:'post',
             data:{
                 status:status,
                 pk:pk
             },
             success:function (data) {
                 console.log(data)
             }
         })
     })
    };
    check.js

    app01

    from django.shortcuts import render,redirect
    from app01 import models
    # Create your views here.
    def login(request):
        if request.method == 'POST':
            username = request.POST.get('username')
            password = request.POST.get('password')
            user_obj = models.User.objects.filter(name=username,pwd=password).first()
            if user_obj:
                # 记录登陆状态
                request.session['user'] = username
                # 记录权限列表
                permission_list = []
                permission_menu_list = []
                res = user_obj.roles.values('permissions__url','permissions__title','permissions__code').distinct()
                for permission in res:
                    permission_list.append(permission.get('permissions__url'))
                    if permission.get('permissions__code') == 'list':
                        permission_menu_list.append({
                            'url':permission.get('permissions__url'),
                            'title':permission.get('permissions__title'),
                        })
                request.session['permission_menu_list'] = permission_menu_list
                request.session['permission_list'] = permission_list
                return redirect('/index')
        return render(request,'login.html')
    
    def logout(request):
        request.session.clear()
        return redirect('/index')
    
    def index(request):
        return render(request,'stark/index.html')
    views.py
    from app01 import models
    from stark.service.stark import site,ModelStark
    from django.utils.safestring import mark_safe
    from django.conf.urls import url
    from django.shortcuts import render,redirect,HttpResponse
    
    class UserConfig(ModelStark):
        list_display = ['name','pwd','roles']
    
    site.register(models.User,UserConfig)
    site.register(models.Role)
    class PermissionConfig(ModelStark):
        list_display = ['title','url']
        list_display_links = ['title']
    site.register(models.Permission,PermissionConfig)
    
    # CRM相关表
    site.register(models.School)
    site.register(models.Course)
    site.register(models.Department)
    site.register(models.UserInfo)
    site.register(models.ClassList)
    
    class CustomerConfig(ModelStark):
        def show_consult_course(self,is_header=False,obj=None):
            if is_header:
                return '咨询课程'
            course_list = []
            for course in obj.course.all():
                course_list.append('<a href="/stark/app01/customer/cancel_course/%s/%s/" style="border: 1px solid blue;padding: 3px 6px">%s</a>'%(obj.pk,course.pk,course.name))
            return mark_safe(' '.join(course_list))
    
        def cancel_course(self, request, customer_id, course_id):
            customer_obj = models.Customer.objects.filter(pk=customer_id).first()
            customer_obj.course.remove(course_id)
            return redirect(self.get_reverse_url('list'))
    
        def extra_url(self):
            tmp = []
            tmp.append(
                url(r'^cancel_course/(d+)/(d+)/', self.cancel_course)
            )
            return tmp
        list_display = ['name','gender',show_consult_course]
    
    
    site.register(models.Customer,CustomerConfig)
    
    site.register(models.ConsultRecord)
    site.register(models.Student)
    
    
    class ClassStudyRecordConfig(ModelStark):
        def patch_init(self,request,queryset):
            # queryset是选中的某个班级当天的课程记录
            tmp = []
            for course_record_obj in queryset:
                student_list = models.Student.objects.filter(class_list=course_record_obj.class_obj.pk)
                for student_obj in student_list:
                    obj = models.StudentStudyRecord(classstudyrecord=course_record_obj,student=student_obj)
                    tmp.append(obj)
            models.StudentStudyRecord.objects.bulk_create(tmp)
        patch_init.desc = '批量生成学生学习记录'
        actions = [patch_init]
    
        def record(self,is_header=False,obj=None):
            if is_header:
                return '记录'
            _url = '/stark/app01/studentstudyrecord/?classstudyrecord=%s'%obj.pk
            return mark_safe("<a href='%s'>记录</a>"%_url)
    
        list_display = ['class_obj','day_num',record]
    site.register(models.ClassStudyRecord,ClassStudyRecordConfig)
    class StudentStudyRecordConfig(ModelStark):
        def patch_late(self,request,queryset):
            queryset.update(record='late')
        patch_late.desc = '批量处理迟到'
        actions = [patch_late]
    
        def work(self,is_header=False,obj=None):
            if is_header:
                return '考勤'
            html = ''
            for k in obj.record_choices:
                if obj.record == k[0]:
                    s = "<option  value='%s' selected>%s</option>"%k
                else:
                    s = "<option  value='%s' >%s</option>"%k
                html += s
            return mark_safe("<select class='xxx' pk=%s>%s</select>"%(obj.pk,html))
    
        def check(self,request):
            status = request.POST.get('status')
            pk = request.POST.get('pk')
            print(status,pk)
            models.StudentStudyRecord.objects.filter(pk=pk).update(record=status)
            return HttpResponse('ok')
    
        def extra_url(self):
            tmp = []
            tmp.append(
                url(r'^check_work/',self.check)
            )
            return tmp
    
        list_display = ['classstudyrecord', 'student', 'record', 'score',work]
    site.register(models.StudentStudyRecord,StudentStudyRecordConfig)
    stark.py
    from django.db import models
    
    # Create your models here.
    # rbac权限相关表格
    class User(models.Model):
        name = models.CharField(max_length=32)
        pwd = models.CharField(max_length=32)
        roles = models.ManyToManyField(to='Role')
    
        def __str__(self):
            return self.name
    
    class Role(models.Model):
        title = models.CharField(max_length=32)
        permissions = models.ManyToManyField(to='Permission')
    
        def __str__(self):
            return self.title
    
    class Permission(models.Model):
        title = models.CharField(max_length=32)
        url = models.CharField(max_length=32)
        code = models.CharField(max_length=32,default='list')
    
        def __str__(self):
            return self.title
    
    
    # CRM相关内部表
    class School(models.Model):
        """
        校区表
        如:
            北京沙河校区
            上海校区
    
        """
        title = models.CharField(verbose_name='校区名称', max_length=32)
    
        def __str__(self):
            return self.title
    
    class Course(models.Model):
        """
        课程表
        如:
            Linux基础
            Linux架构师
            Python自动化开发精英班
            Python自动化开发架构师班
            Python基础班
            go基础班
        """
        name = models.CharField(verbose_name='课程名称', max_length=32)
    
        def __str__(self):
            return self.name
    
    class Department(models.Model):
        """
        部门表
        市场部     1000
        销售       1001
    
        """
        title = models.CharField(verbose_name='部门名称', max_length=16)
        code = models.IntegerField(verbose_name='部门编号', unique=True, null=False)
    
        def __str__(self):
            return self.title
    
    class UserInfo(models.Model):
        """
        员工表
        """
    
        name = models.CharField(verbose_name='员工姓名', max_length=16)
        email = models.EmailField(verbose_name='邮箱', max_length=64)
        depart = models.ForeignKey(verbose_name='部门', to="Department",to_field="code")
        user=models.OneToOneField("User",default=1)
        def __str__(self):
            return self.name
    
    class ClassList(models.Model):
        """
        班级表
        如:
            Python全栈  面授班  5期  10000  2017-11-11  2018-5-11
        """
        school = models.ForeignKey(verbose_name='校区', to='School')
        course = models.ForeignKey(verbose_name='课程名称', to='Course')
        semester = models.IntegerField(verbose_name="班级(期)")
    
    
        price = models.IntegerField(verbose_name="学费")
        start_date = models.DateField(verbose_name="开班日期")
        graduate_date = models.DateField(verbose_name="结业日期", null=True, blank=True)
        memo = models.CharField(verbose_name='说明', max_length=256, blank=True, null=True, )
    
        teachers = models.ManyToManyField(verbose_name='任课老师', to='UserInfo',limit_choices_to={'depart':1002})
        tutor = models.ForeignKey(verbose_name='班主任', to='UserInfo',related_name="class_list",limit_choices_to={'depart':1006})
    
    
        def __str__(self):
            return "{0}({1}期)".format(self.course.name, self.semester)
    
    
    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)
    models.py
     
  • 相关阅读:
    指针
    const
    指针数组和指向数组的指针
    extjs初探之由浅入深目录
    ie6字体设置13px引发的问题
    在IAR下通过Jlink将程序直接下载到Flash指定地址
    提高C语言程序运行稳定性的方法
    C/C++编程习惯
    释放QQ占用的C盘空间
    非阻塞算法思想在关系数据库应用程序开发中的使用
  • 原文地址:https://www.cnblogs.com/ShenJunHui6/p/10850093.html
Copyright © 2020-2023  润新知