zoukankan      html  css  js  c++  java
  • Django项目:CRM(客户关系管理系统)--71--61PerfectCRM实现CRM学生上传作业

     1 # student_urls.py
     2 # ————————60PerfectCRM实现CRM学生上课记录————————
     3 from django.conf.urls import url
     4 from bpm.student import student_views
     5 
     6 urlpatterns = [
     7     url(r'^student_course/$', student_views.student_course, name='student_course'),   #学生报名的课程
     8     url(r'^studyrecords/(d+)/$', student_views.studyrecords, name='studyrecords'),  # #学生上课记录列表StudyRecord
     9 
    10     # ————————61PerfectCRM实现CRM学生上传作业————————
    11     url( r'^homework_detail/(d+)/(d+)/$', student_views.homework_detail, name='homework_detail' ),  # 作业详情
    12     # ————————61PerfectCRM实现CRM学生上传作业————————
    13 ]
    14 # ————————60PerfectCRM实现CRM学生上课记录————————
    # student_urls.py

     1 # student_views.py
     2 # ————————60PerfectCRM实现CRM学生上课记录————————
     3 from django.shortcuts import render #页面返回
     4 from crm import models #数据库
     5 from  django.contrib.auth.decorators import login_required # 登陆后页面才能访问
     6 #学生报名的课程
     7 @login_required # 登陆后页面才能访问
     8 def student_course(request):
     9     enrollmentlist=request.user.stu_account.enrollment_set.all()#根据账号表关联的ID获取06学员报名信息表
    10     return  render(request, 'bpm_student/student_course.html', locals())
    11 
    12 #学生上课记录列表
    13 @login_required # 登陆后页面才能访问
    14 def studyrecords(request,enroll_obj_id):
    15     enroll_obj=models.Enrollment.objects.get(id=enroll_obj_id)#根据ID获取06学员报名信息表
    16     studyrecordlist=enroll_obj.studyrecord_set.all()#根据06学员报名信息表的ID获取09学习纪录
    17     return render(request,'bpm_student/studyrecords.html',locals())
    18 
    19 # ————————60PerfectCRM实现CRM学生上课记录————————
    20 
    21 # ————————61PerfectCRM实现CRM学生上传作业————————
    22 from django.contrib.auth.decorators import login_required #登陆才能访问
    23 from PerfectCRM import settings #静态配置文件  #作业上传 # 上传路径
    24 import os,json,time #系统操作
    25 from django.shortcuts import HttpResponse #页面返回
    26 from django.shortcuts import redirect #页面返回
    27 #作业详情
    28 @login_required#登陆才能访问
    29 def homework_detail(request,enroll_obj_id,studyrecord_id):
    30     studyrecord_obj=models.StudyRecord.objects.get(id=studyrecord_id)#取学习记录 对象
    31     enroll_obj=models.Enrollment.objects.get(id=enroll_obj_id)#取班级对象
    32 
    33     #               作业根目录    班级ID      上课记录ID               学习记录ID
    34     homework_path="{base_dir}/{class_id}/{course_record_id}/{studyercord_id}/".format(
    35         base_dir=settings.HOMEWORK_DATA, #静态配置文件
    36         class_id=studyrecord_obj.student.enrolled_class_id,#09学习纪录#学生名字#所报班级ID号
    37         course_record_id=studyrecord_obj.course_record_id,#09学习纪录#每节课上课纪录表
    38         studyercord_id=studyrecord_obj.id##09学习纪录
    39     )
    40     print('homework_path路径:',studyrecord_obj.student.enrolled_class_id,studyrecord_obj.course_record_id,studyrecord_obj.id)
    41 
    42     if os.path.exists(homework_path):#判断目录是否存在
    43         file_lists = []  # 已经上传的文件列表
    44         for file_name in os.listdir( homework_path ):
    45             f_path = '%s/%s' % (homework_path, file_name)  # 文件名字
    46             modify_time = time.strftime( "%Y-%m-%d %H:%M:%S", time.gmtime( os.stat( f_path ).st_mtime ) )  # 文件上传时间
    47             file_lists.append( [file_name, os.stat( f_path ).st_size, modify_time] )  # 添加到文件列表#文件名字#文件大小文件上传时间
    48 
    49 
    50     if request.method=="POST":#上传
    51         ret=False
    52         data=request.POST.get('data') #ajax
    53         if data:#如果有删除动作
    54             del_f_path="%s/%s"%(homework_path,data)#文件路径
    55             print('删除文件,路径:',del_f_path)
    56             os.remove(del_f_path) #删除
    57             ret=True
    58             return HttpResponse(json.dumps(ret))#ret=False
    59         if request.is_ajax():  # ajax上传图片 #异步提交
    60             print("POST",request.POST)
    61             if not os.path.isdir( homework_path ):  # 没有目录 #isdir返回true,如果路径名是指现有的目录。
    62                 os.makedirs( homework_path, exist_ok=True )  # 创建目录  
    63             for k,v in request.FILES.items():#上传的文件
    64                 with open('%s/%s'%(homework_path,v.name),'wb') as f:#chunk 写入文件
    65                     for chunk in v.chunks(): #循环写文件
    66                         f.write(chunk)
    67             return HttpResponse( json.dumps( {"status": 0, 'mag': "上传完成!", 'file_lists': file_lists} ) )  # 上传文件返回
    68 
    69     if request.method=="POST":#上传
    70         link = request.POST.get( 'link' )  # 让页面POST提交的值,在页面GET后仍然存在显示
    71         if link:
    72             homework_link=models.StudyRecord.objects.filter( id=studyrecord_id ).update(homework_link=link)
    73             return redirect('/bpm/homework_detail/%s/%s/' %(enroll_obj_id,studyrecord_id) )#跳转到enrollment_rejection
    74     return render(request,'bpm_student/homework_detail.html',locals())
    75 # ————————61PerfectCRM实现CRM学生上传作业————————
    # student_views.py

      1 # settings.py
      2 
      3 """
      4 Django settings for PerfectCRM project.
      5 
      6 Generated by 'django-admin startproject' using Django 2.0.3.
      7 
      8 For more information on this file, see
      9 https://docs.djangoproject.com/en/2.0/topics/settings/
     10 
     11 For the full list of settings and their values, see
     12 https://docs.djangoproject.com/en/2.0/ref/settings/
     13 """
     14 
     15 import os
     16 
     17 # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
     18 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
     19 
     20 
     21 # Quick-start development settings - unsuitable for production
     22 # See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/
     23 
     24 # SECURITY WARNING: keep the secret key used in production secret!
     25 SECRET_KEY = 'atkhzsd7emv4_okn@ynhji)p)qbpuvhq+a7@yx5=chaa0$l_br'
     26 
     27 # SECURITY WARNING: don't run with debug turned on in production!
     28 DEBUG = True
     29 
     30 ALLOWED_HOSTS = []
     31 
     32 
     33 # Application definition
     34 
     35 INSTALLED_APPS = [
     36     'django.contrib.admin',
     37     'django.contrib.auth',
     38     'django.contrib.contenttypes',
     39     'django.contrib.sessions',
     40     'django.contrib.messages',
     41     'django.contrib.staticfiles',
     42     
     43 # ————————04PerfectCRM实现King_admin注册功能————————
     44     # 'crm.apps.CrmConfig',
     45     'crm',
     46 # ————————04PerfectCRM实现King_admin注册功能————————
     47 
     48 # ————————02PerfectCRM创建ADMIN页面————————
     49     'king_admin',
     50 # ————————02PerfectCRM创建ADMIN页面————————
     51     # ————————38PerfectCRM实现全局账号登录注销————————
     52     'gbacc',
     53     # ————————38PerfectCRM实现全局账号登录注销————————
     54 
     55     # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
     56     'bpm',
     57     # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
     58 
     59 ]
     60 
     61 MIDDLEWARE = [
     62     'django.middleware.security.SecurityMiddleware',
     63     'django.contrib.sessions.middleware.SessionMiddleware',
     64     'django.middleware.common.CommonMiddleware',
     65     'django.middleware.csrf.CsrfViewMiddleware',
     66     'django.contrib.auth.middleware.AuthenticationMiddleware',
     67     'django.contrib.messages.middleware.MessageMiddleware',
     68     'django.middleware.clickjacking.XFrameOptionsMiddleware',
     69 ]
     70 
     71 ROOT_URLCONF = 'PerfectCRM.urls'
     72 
     73 TEMPLATES = [
     74     {
     75         'BACKEND': 'django.template.backends.django.DjangoTemplates',
     76 # ————————02PerfectCRM创建ADMIN页面————————
     77         'DIRS': [os.path.join(BASE_DIR, 'templates'),
     78                   os.path.join(BASE_DIR, 'king_admin/king_templates'),
     79 
     80 # ————————03PerfectCRM创建基本数据————————
     81                   os.path.join(BASE_DIR, 'DBadd/DBadd_templates'),
     82 # ————————03PerfectCRM创建基本数据————————
     83                 # ————————38PerfectCRM实现全局账号登录注销————————
     84                   os.path.join(BASE_DIR, 'gbacc/gbacc_templates'),
     85                 # ————————38PerfectCRM实现全局账号登录注销————————
     86 
     87                 # ————————47PerfectCRM实现CRM客户报名流程————————
     88                 os.path.join(BASE_DIR, 'bpm/bpm_templates'), ]
     89                 # ————————47PerfectCRM实现CRM客户报名流程————————
     90 
     91 ,
     92 # ————————02PerfectCRM创建ADMIN页面————————
     93         'APP_DIRS': True,
     94         'OPTIONS': {
     95             'context_processors': [
     96                 'django.template.context_processors.debug',
     97                 'django.template.context_processors.request',
     98                 'django.contrib.auth.context_processors.auth',
     99                 'django.contrib.messages.context_processors.messages',
    100             ],
    101         },
    102     },
    103 ]
    104 
    105 WSGI_APPLICATION = 'PerfectCRM.wsgi.application'
    106 
    107 
    108 # Database
    109 # https://docs.djangoproject.com/en/2.0/ref/settings/#databases
    110 
    111 DATABASES = {
    112     'default': {
    113         'ENGINE': 'django.db.backends.sqlite3',
    114         'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    115     }
    116 }
    117 
    118 
    119 # Password validation
    120 # https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators
    121 
    122 AUTH_PASSWORD_VALIDATORS = [
    123     {
    124         'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    125     },
    126     {
    127         'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    128     },
    129     {
    130         'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    131     },
    132     {
    133         'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    134     },
    135 ]
    136 
    137 
    138 # Internationalization
    139 # https://docs.djangoproject.com/en/2.0/topics/i18n/
    140 
    141 # ————————01PerfectCRM基本配置ADMIN————————
    142 #LANGUAGE_CODE = 'en-us'
    143 
    144 #英文转中文方法
    145 LANGUAGE_CODE = 'zh-Hans'
    146 # ————————01PerfectCRM基本配置ADMIN————————
    147 
    148 TIME_ZONE = 'UTC'
    149 
    150 USE_I18N = True
    151 
    152 USE_L10N = True
    153 
    154 USE_TZ = True
    155 
    156 
    157 # Static files (CSS, JavaScript, Images)
    158 # https://docs.djangoproject.com/en/2.0/howto/static-files/
    159 
    160 STATIC_URL = '/static/'
    161 
    162 # ————————01PerfectCRM基本配置ADMIN————————
    163 STATICFILES_DIRS = [os.path.join(BASE_DIR,'king_admin/static'),
    164 # ————————01PerfectCRM基本配置ADMIN————————
    165                     # ————————38PerfectCRM实现全局账号登录注销————————
    166                     os.path.join(BASE_DIR, 'gbacc/static'),
    167                     # ————————38PerfectCRM实现全局账号登录注销————————
    168                     
    169                     # ————————47PerfectCRM实现CRM客户报名流程————————
    170                     os.path.join(BASE_DIR, 'bpm/static'),]
    171                     # ————————47PerfectCRM实现CRM客户报名流程————————
    172 
    173 
    174 # ————————34PerfectCRM实现CRM自定义用户————————
    175 AUTH_USER_MODEL = 'crm.UserProfile'#使用自定的admin 表单
    176 # ————————34PerfectCRM实现CRM自定义用户————————
    177 
    178 
    179 
    180 # ————————44PerfectCRM实现账号快速注册登陆————————
    181 # send e-mail
    182 EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'  #email后端
    183 EMAIL_USE_TLS = False   #是否使用TLS安全传输协议
    184 EMAIL_USE_SSL = True    #是否使用SSL加密,qq企业邮箱要求使用
    185 EMAIL_HOST = 'smtp.sina.cn'   #发送邮件的邮箱 的 SMTP服务器       #根据情况重新配置
    186 EMAIL_PORT = 465                 #发件箱的SMTP服务器端口 #一般不需要修改465
    187 EMAIL_HOST_USER = 'perfectcrm@sina.cn'    #发送邮件的邮箱账号     #根据情况重新配置  #perfectcrm@sina.cn   pydjango@sina.cn
    188 EMAIL_HOST_PASSWORD = 'admin123456'         #发送邮件的邮箱密码    #根据情况重新配置
    189 
    190 # ————————44PerfectCRM实现账号快速注册登陆————————
    191 
    192 
    193 # ————————46PerfectCRM实现登陆后页面才能访问————————
    194 LOGIN_URL = '/gbacc/gbacc_login/'# login_url 配置      #默认 /accounts/login/  #注意: / (绝对路径)
    195 # ————————46PerfectCRM实现登陆后页面才能访问————————
    196 
    197 # ————————51PerfectCRM实现CRM客户报名流程学生合同上传照片————————
    198 ENROLLED_DATA='%s/bpm/static/enrolled_data'%BASE_DIR#证件上传 # 上传路径
    199 # ————————51PerfectCRM实现CRM客户报名流程学生合同上传照片————————
    200 
    201 
    202 # ————————61PerfectCRM实现CRM学生上传作业————————
    203 HOMEWORK_DATA='%s/bpm/static/homeworks'%BASE_DIR  #作业上传 # 上传路径
    204 # ————————61PerfectCRM实现CRM学生上传作业————————
    # settings.py

      1 #models.py
      2 
      3 # ————————01PerfectCRM基本配置ADMIN————————
      4 
      5 from django.db import models
      6 # Create your models here.
      7 
      8 """
      9 #运行 Terminal
     10 #    生成 数据表
     11 #    python manage.py makemigrations
     12 #   数据表 迁移
     13 #    python manage.py migrate
     14 """
     15 
     16 """01校区表"""
     17 class Branch(models.Model):
     18     name = models.CharField(max_length=128,unique=True) #校区名#CharField作用是保存文本,定长的变量类型
     19     addr = models.CharField(max_length=128) #地址
     20     def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
     21         return self.name #返回 #校区名
     22     class Meta: #通过一个内嵌类 "class Meta" 给你的 model 定义元数据
     23         verbose_name_plural =  "01校区表" #verbose_name_plural给你的模型类起一个更可读的名字
     24 
     25 """02班级表"""
     26 class ClassList(models.Model):
     27     #ForeignKey就是表与表之间的某种约定的关系  #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
     28     branch = models.ForeignKey("Branch",on_delete=models.CASCADE)#校区    关联到  校区表
     29     course = models.ForeignKey("Course",on_delete=models.CASCADE) #课程   关联到   课程表
     30 
     31     # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
     32     contract = models.ForeignKey('ContractTemplate', blank=True, null=True, default=1,on_delete=models.CASCADE)  # 合同表
     33     # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
     34 
     35     class_type_choices = ( #上课形式
     36                           (0,'面授(脱产)'),
     37                           (1,'面授(周末)'),
     38                           (2,'网络班'),)
     39     #PositiveSmallIntegerField正小整数 0 ~ 32767 #choices是Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
     40     class_type = models.SmallIntegerField(choices=class_type_choices)#上课形式
     41 
     42     #PositiveSmallIntegerField正小整数 0 ~ 32767
     43     semester = models.PositiveSmallIntegerField(verbose_name="学期") #课程的第几期
     44 
     45     #ManyToManyField多对多和外键工作方式相同,只不过我们处理的是QuerySet而不是模型实例。
     46     teachers = models.ManyToManyField("UserProfile") # 老师   关联到    账号表
     47 
     48     start_date = models.DateField(verbose_name="开班日期") #DateField 日期格式 YYYY-MM-DD #verbose_name是Admin中显示的字段名称
     49 
     50     # DateField 日期格式 YYYY-MM-DD #verbose_name是Admin中显示的字段名称 #Django可空#数据库可以为空
     51     end_date = models.DateField(verbose_name="结业日期",blank=True,null=True)
     52 
     53     def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
     54         return "%s %s %s" %(self.branch,self.course,self.semester) #返回 #%s格式化输出字符串 #校区#课程# 学期
     55     class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
     56         unique_together=('branch','course','semester')  #联合索引
     57         verbose_name_plural = "02班级表" #verbose_name_plural给你的模型类起一个更可读的名字
     58 
     59 """03课程表,可以报名那些课程"""
     60 class Course(models.Model):
     61     name = models.CharField(max_length=64,unique=True)#课程名 #CharField作用是保存文本,定长的变量类型
     62     price = models.PositiveSmallIntegerField(verbose_name="学费")#学费#PositiveSmallIntegerField正小整数 0 ~ 32767
     63     period = models.PositiveSmallIntegerField(verbose_name="周期(月)") #PositiveSmallIntegerField正小整数 0 ~ 32767
     64     outline = models.TextField() #课程大纲  #文本类型
     65     def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
     66         return self.name #返回 #课程名
     67     class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
     68         verbose_name_plural =  "03课程表"#verbose_name_plural给你的模型类起一个更可读的名字
     69 
     70 '''04客户信息表'''
     71 class Customer(models.Model):
     72     name = models.CharField(max_length=32,blank=True,null=True)#客户名#CharField定长文本 #名字最长32 # Django可空 #数据库可以为空
     73     qq = models.CharField(max_length=64,unique=True) #QQ号#CharField定长文本 #名字最长64 #唯一,不能重复
     74     qq_name = models.CharField(max_length=64,blank=True,null=True)#QQ名 #CharField定长文本 #名字最长64 # Django可空 #数据库可以为空
     75     phone = models.CharField(max_length=64,blank=True,null=True)#手机号 #CharField定长文本 #名字最长64 # Django可空 #数据库可以为空
     76 
     77     # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
     78     id_num=models.CharField(max_length=64,blank=True,null=True,verbose_name='身份证号')#身份证号
     79     email=models.EmailField(max_length=64,blank=True,null=True,verbose_name='邮箱')#email
     80     sex_choices=((0,'保密'),(1,''),(2,''))
     81     sex=models.SmallIntegerField(choices=sex_choices,default=0,verbose_name='性别')
     82     # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
     83 
     84     # ————————53PerfectCRM实现CRM客户报名流程缴费————————
     85     status_choices = ((0, '已报名'), (1, '未报名'), (2, '已退学'))
     86     status = models.SmallIntegerField(choices=status_choices, default=1)  # 学员状态
     87     # ————————53PerfectCRM实现CRM客户报名流程缴费————————
     88 
     89     source_choices = ( #客户渠道来源 (内存生成)
     90                       (0,'转介绍'),
     91                       (1,'QQ群'),
     92                       (2,'官网'),
     93                       (3,'百度推广'),
     94                       (4,'51CTO'),
     95                       (5,'知乎'),
     96                       (6,'市场推广'),)
     97     #PositiveSmallIntegerField正小整数 0 ~ 32767(省空间)#choices是Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
     98     source = models.SmallIntegerField(choices=source_choices)#客户渠道来源
     99 
    100     #CharField定长文本#verbose_name是Admin中显示的字段名称#名字最长64 # Django可空 #数据库可以为空
    101     referral_from = models.CharField(verbose_name="转介绍人qq",max_length=64,blank=True,null=True) #来自谁介绍的
    102 
    103     #ForeignKey就是表与表之间的某种约定的关系#verbose_name是Admin中显示的字段名称 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
    104     consult_courses = models.ForeignKey("Course",verbose_name="咨询课程", on_delete=models.CASCADE) #关联到 课程表
    105 
    106     content= models.TextField(verbose_name="咨询详情") #TextField无限制长度的文本#verbose_name是Admin中显示的字段名称
    107 
    108     #ManyToManyField多对多和外键工作方式相同,只不过我们处理的是QuerySet而不是模型实例。
    109     tags = models.ManyToManyField("Tag",blank=True)#多对多关联到 标签表
    110 
    111     #ForeignKey就是表与表之间的某种约定的关系  #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
    112     consultant = models.ForeignKey("UserProfile", on_delete=models.CASCADE) #关联到  账号表
    113 
    114     memo = models.TextField(blank=True,null=True)#备注#TextField无限制长度的文本#Django可空#数据库可以为空
    115 
    116     #DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读)
    117     date =  models.DateTimeField(auto_now_add=True)#创建时间(数据库自增)
    118 
    119     def __str__(self): #__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
    120         return self.qq  #返回 #QQ号
    121 
    122     class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
    123         verbose_name_plural =  "04客户表" #verbose_name_plural给你的模型类起一个更可读的名字
    124 
    125 # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
    126 #合同模版
    127 class ContractTemplate(models.Model):
    128     name=models.CharField('合同名称',max_length=64,unique=True)
    129     template=models.TextField()
    130 
    131     def __str__(self):
    132         return self.name
    133     class Meta:
    134         verbose_name_plural='合同表'
    135 # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
    136 
    137 
    138 """05客户跟进表"""
    139 class CustomerFollowUp(models.Model):
    140 
    141     #ForeignKey就是表与表之间的某种约定的关系 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
    142     customer = models.ForeignKey("Customer", on_delete=models.CASCADE)#客户名 #关联到  客户信息表
    143 
    144     content = models.TextField(verbose_name="跟进内容")#跟进的内容#TextField无限制长度的文本#verbose_name是Admin中显示的字段名称
    145 
    146     #ForeignKey就是表与表之间的某种约定的关系  #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
    147     consultant =models.ForeignKey("UserProfile", on_delete=models.CASCADE) #关联到  账号表
    148 
    149     intention_choices =(  #报名状态
    150                         (0,'2周内报名'),
    151                         (1,'1个月内报名'),
    152                         (2,'近期无报名计划'),
    153                         (3,'已在其它机构报名'),
    154                         (4,'已报名'),
    155                         (5,'已拉黑'),)
    156     #PositiveSmallIntegerField正小整数 0 ~ 32767(省空间)#choices是Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
    157     intention=models.SmallIntegerField(choices=intention_choices) #报名状态
    158 
    159     #DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读)
    160     date =  models.DateTimeField(auto_now_add=True)#创建时间(数据库自增)
    161 
    162     def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
    163         return "<%s:%s>" %(self.customer.qq,self.intention) #返回#格式化字符串#跨表里的QQ号#报名状态
    164     class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
    165         verbose_name_plural =  "05客户跟进表"#verbose_name_plural给你的模型类起一个更可读的名字
    166 
    167 """06学员报名信息表"""
    168 class Enrollment(models.Model):
    169     # ForeignKey就是表与表之间的某种约定的关系#verbose_name是Admin中显示的字段名称 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
    170     customer = models.ForeignKey("Customer",on_delete=models.CASCADE)#学员名字 #关联到  客户信息表
    171     enrolled_class = models.ForeignKey("ClassList",verbose_name="所报班级",on_delete=models.CASCADE)#关联到  班级表
    172     consultant = models.ForeignKey("UserProfile",verbose_name="课程顾问",on_delete=models.CASCADE) #关联到  账号表
    173 
    174     # ————————52PerfectCRM实现CRM客户报名流程学生合同审核————————
    175     contract_review = models.CharField(max_length=256, blank=True, null=True, verbose_name="合同审核")  # 合同审核
    176     # ————————52PerfectCRM实现CRM客户报名流程学生合同审核————————
    177 
    178     #BooleanField布尔值类型#default=False默认(True)不允许出现空字符#verbose_name是Admin中显示的字段名称
    179     contract_agreed = models.BooleanField(default=False,verbose_name="学员已经同意合同")#学员看合同
    180     contract_approved = models.BooleanField(default=False,verbose_name="合同已经审核") #谁审核
    181 
    182     # ————————53PerfectCRM实现CRM客户报名流程缴费————————
    183     Pay_cost= models.BooleanField(default=False,verbose_name="缴费") #缴费状态#是不是交定金
    184     # ————————53PerfectCRM实现CRM客户报名流程缴费————————
    185 
    186     # DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读)
    187     date = models.DateTimeField(auto_now_add=True)#创建时间(数据库自增)
    188 
    189     def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
    190         # ————————57PerfectCRM实现admin批量生成上课记录————————
    191         # return "%s %s" %(self.customer,self.enrolled_class)#返回#格式化字符串#学员名字#所报班级
    192         return " 学员:%s |QQ: %s |班级:%s" %(self.customer.name,self.customer,self.enrolled_class)#返回#格式化字符串#学员名字#所报班级
    193         # ————————57PerfectCRM实现admin批量生成上课记录————————
    194     class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
    195         unique_together =  ("customer","enrolled_class")#联合索引
    196         verbose_name_plural =  "06学员报名信息表"#verbose_name_plural给你的模型类起一个更可读的名字
    197 
    198 """07缴费记录表"""
    199 class Payment(models.Model):
    200     #ForeignKey就是表与表之间的某种约定的关系#verbose_name是Admin中显示的字段名称 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
    201     customer = models.ForeignKey("Customer",on_delete=models.CASCADE)#学员名字        关联到  客户信息表
    202     course = models.ForeignKey("Course",verbose_name="所报课程",on_delete=models.CASCADE)#关联到  课程表
    203 
    204     #PositiveSmallIntegerField正小整数 0 ~ 32767 #verbose_name是Admin中显示的字段名称#默认值=500
    205     amount = models.PositiveIntegerField(verbose_name="数额",default=500)#缴费数额
    206 
    207     #ForeignKey就是表与表之间的某种约定的关系#CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
    208     consultant = models.ForeignKey("UserProfile",on_delete=models.CASCADE)#缴费给谁 关联到  账号表 #财务人员
    209 
    210     #DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读)
    211     date=models.DateTimeField(auto_now_add=True)#创建时间(数据库自增)
    212 
    213     def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
    214         return "%s %s" %(self.customer,self.amount)#返回#格式化字符串#学员名字#缴费数额
    215     class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
    216         verbose_name_plural = "07缴费记录表"#verbose_name_plural给你的模型类起一个更可读的名字
    217 
    218 """08每节课上课纪录表"""
    219 class CourseRecord(models.Model):
    220     # ForeignKey就是表与表之间的某种约定的关系#verbose_name是Admin中显示的字段名称 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
    221     from_class = models.ForeignKey("ClassList",verbose_name="班级",on_delete=models.CASCADE) #那个班级
    222 
    223     #PositiveSmallIntegerField正小整数 0 ~ 32767 #verbose_name是Admin中显示的字段名称
    224     day_num = models.PositiveSmallIntegerField(verbose_name="第几节(天)") #第几节课
    225 
    226     # ForeignKey就是表与表之间的某种约定的关系 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
    227     teacher = models.ForeignKey("UserProfile",on_delete=models.CASCADE)#老师是谁    关联到    账号表
    228 
    229     #BooleanField布尔值类型#default=True默认(True)不允许出现空字符
    230     has_homework = models.BooleanField(default=True) #有没有作业
    231 
    232     # CharField定长文本#名字最长128#Django可空#数据库可以为空
    233     homework_title = models.CharField(max_length=128,blank=True,null=True) #作业标题
    234 
    235     #TextField无限制长度的文本#Django可空#数据库可以为空
    236     homework_content = models.TextField(blank=True,null=True) #作业内容
    237 
    238     #TextField无限制长度的文本#verbose_name是Admin中显示的字段名称
    239     outline =models.TextField(verbose_name="本节课程大纲") #课程主要讲什么
    240 
    241     # DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读)
    242     date = models.DateField(auto_now_add=True)#创建时间(数据库自增)
    243 
    244     def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
    245         return " %s:%s" %(self.from_class,self.day_num)#返回#格式化字符串#班级#第几节(天)
    246     class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
    247         unique_together = ("from_class","day_num") #联合索引
    248         verbose_name_plural = "08每节课上课纪录表" #verbose_name_plural给你的模型类起一个更可读的名字
    249 
    250 """09学习纪录"""
    251 class StudyRecord(models.Model):
    252     # ForeignKey就是表与表之间的某种约定的关系 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
    253     student = models.ForeignKey("Enrollment",on_delete=models.CASCADE)#学生名字   关联到    学员报名信息表
    254     course_record = models.ForeignKey("CourseRecord",on_delete=models.CASCADE)#开课记录   # 关联到    每节课上课纪录表
    255 
    256     attendance_choices = (# 本节课上课状态记录
    257                             (0,"已签到"),
    258                             (1,"迟到"),
    259                             (2,"缺勤"),
    260                             (3,"早退"),)
    261     #PositiveSmallIntegerField正小整数 0 ~ 32767(省空间)#choices是Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
    262     attendance = models.SmallIntegerField(choices=attendance_choices) # 本节课上课状态记录
    263 
    264     # ————————61PerfectCRM实现CRM学生上传作业————————
    265     homework_link = models.TextField(blank=True,null=True)#作业链接 #TextField无限制长度的文本#Django可空#数据库可以为空
    266     # ————————61PerfectCRM实现CRM学生上传作业————————
    267 
    268     score_choices = (#学习成绩
    269                      (100,"A+"),
    270                      (90,"A"),
    271                      (85,"B+"),
    272                      (80,"B"),
    273                      (75,"B-"),
    274                      (70,"C+"),
    275                      (65,"C"),
    276                      (40,"C-"),
    277                      (-20,"D"),
    278                      (-50,"COPY"),
    279                      (0,"N/A"),)
    280     #PositiveSmallIntegerField正小整数 0 ~ 32767(省空间)#choices是Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
    281     score = models.SmallIntegerField(choices=score_choices) #学习成绩
    282 
    283 
    284     memo = models.TextField(blank=True,null=True)#TextField无限制长度的文本#Django可空#数据库可以为空
    285 
    286     # DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读)
    287     date = models.DateField(auto_now_add=True)#创建时间(数据库自增)
    288 
    289     def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
    290         return "%s %s %s" % (self.student, self.course_record, self.score)#返回#格式化字符串#学生名字#开课记录#学习成绩
    291     class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
    292         unique_together = ('student','course_record')#联合索引#学生名字#开课记录
    293         verbose_name_plural =  "09学习纪录"#verbose_name_plural给你的模型类起一个更可读的名字
    294 
    295 # ————————34PerfectCRM实现CRM自定义用户————————
    296 # """10账号表"""
    297 # class UserProfile(models.Model):
    298 #     from django.contrib.auth.models import User  # 使用django内置的用户表
    299 #
    300 #     #OneToOneField一对一  #User是django Admin里的账号表#CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
    301 #     user = models.OneToOneField(User,on_delete=models.CASCADE)# 用户名 #创建外键,关联django用户表
    302 #
    303 #     name = models.CharField(max_length=32) #账号名(扩展用户字段)#CharField定长文本
    304 #
    305 #     #ManyToManyField多对多和外键工作方式相同,只不过我们处理的是QuerySet而不是模型实例。#Django可空
    306 #     roles = models.ManyToManyField("Role",blank=True) #角色(权限)   # 双向一对多==多对多
    307 #
    308 #     def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
    309 #         return self.name #返回 #账号名
    310 #     class Meta: #通过一个内嵌类 "class Meta" 给你的 model 定义元数据
    311 #         verbose_name_plural = "10账号表"#verbose_name_plural给你的模型类起一个更可读的名字
    312 # ————————34PerfectCRM实现CRM自定义用户————————
    313 
    314 # ————————34PerfectCRM实现CRM自定义用户————————
    315 #10账号表,创建用户和超级用户
    316 from django.contrib.auth.models import BaseUserManager
    317 class UserProfileManager(BaseUserManager):
    318     def create_user(self, email, name, password=None):
    319         """
    320       创建并保存一个用户用给定的邮件,日期
    321       出生和密码。
    322         """
    323         if not email:#没有email 报错
    324             raise ValueError('用户必须有一个电子邮件地址')
    325 
    326         user = self.model(
    327             email=self.normalize_email(email),#验证邮箱格式
    328             name=name,
    329         )
    330         user.set_password(password)#加密
    331         user.is_active = True
    332         user.save(using=self._db)
    333         return user
    334     def create_superuser(self, email, name, password):
    335         """
    336       创建并保存一个超级用户具有给定邮件,日期
    337       出生和密码。
    338         """
    339         user = self.create_user(email,
    340             password=password,
    341             name=name
    342         )
    343         user.is_active = True
    344         user.is_superuser = True
    345         user.save(using=self._db)
    346         return user
    347 
    348 """10账号表"""
    349 """
    350 
    351 #删除数据库
    352 
    353 #调用objects = UserProfileManager()#创建账号 #关联这个函数
    354 
    355 #运行 Terminal
    356 #    生成 数据表
    357 #    python manage.py makemigrations
    358 #   数据表 迁移
    359 #    python manage.py migrate
    360 Django Admin里账号密码重置方法
    361 #运行 Terminal  
    362 python manage.py createsuperuser
    363 
    364 Email address:          admin@qq.com
    365 用户名 :                 admin
    366 Password:               admin123456
    367 Password (again):       admin123456
    368 """
    369 from django.contrib.auth.models import AbstractBaseUser
    370 # ————————35PerfectCRM实现CRM重写Admin密码修改————————
    371 from django.utils.translation import ugettext_lazy as _  # 语言国际化
    372 from django.utils.safestring import mark_safe
    373 from django.contrib.auth.models import PermissionsMixin
    374 # class UserProfile(AbstractBaseUser):
    375 class UserProfile(AbstractBaseUser,PermissionsMixin):
    376 # ————————35PerfectCRM实现CRM重写Admin密码修改————————
    377     email=models.EmailField(
    378         verbose_name='邮箱账号',
    379         max_length=255,
    380         unique=True#唯一  #登陆账号
    381     )
    382     name=models.CharField(max_length=32,verbose_name='用户名')
    383 
    384     # ————————35PerfectCRM实现CRM重写Admin密码修改————————
    385     password = models.CharField(_('password'), max_length=128, help_text=mark_safe('''<a href="../password/">修改密码</a>'''))
    386     # ————————35PerfectCRM实现CRM重写Admin密码修改————————
    387 
    388     is_active = models.BooleanField(default=True,verbose_name='合法账号')#权限#合法账号
    389     is_superuser = models.BooleanField(default=False,verbose_name='超级账号') #超级账号
    390     objects = UserProfileManager()#创建账号 #关联这个函数
    391     USERNAME_FIELD ='email'#指定做为  #登陆账号
    392     REQUIRED_FIELDS = ['name']#必填字段
    393 
    394 
    395     # ————————60PerfectCRM实现CRM学生上课记录————————
    396     stu_account = models.ForeignKey( "Customer", verbose_name='关联学员帐号', blank=True, null=True, on_delete=models.CASCADE,
    397                                      help_text='报名成功后创建关联帐户' )
    398     # ————————60PerfectCRM实现CRM学生上课记录————————
    399 
    400     def get_full_name(self):
    401         return self.email
    402     def get_short_name(self):
    403         #用户确认的电子邮件地址
    404         return self.email
    405     def __str__(self):
    406         return self.name
    407     def has_perm(self,perm,obj=None):
    408         #指明用户是否被认为活跃的。以反选代替删除帐号。
    409         #最简单的可能的答案:是的,总是
    410         return True   #有效 账号
    411     def has_module_perms(self, app_label):
    412         #指明用户是否可以登录到这个管理站点。
    413         # 最简单的可能的答案:是的,总是
    414         return True #职员状态
    415     @property
    416     def is_staff(self):
    417         '''“用户的员工吗?”'''
    418         #最简单的可能的答案:所有管理员都是员工
    419         return self.is_superuser#是不是超级用户状态
    420 # AUTH_USER_MODEL = 'crm.UserProfile'#使用自定的admin 表单   #settings.py
    421 # ————————34PerfectCRM实现CRM自定义用户————————
    422 
    423 """11角色表"""
    424 class Role(models.Model):
    425     name = models.CharField(unique=True,max_length=32)#角色名#CharField定长文本#角色名不可以重复#最长度=32字节
    426     def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
    427         return self.name#返回 #角色名
    428     class Meta: #通过一个内嵌类 "class Meta" 给你的 model 定义元数据
    429         verbose_name_plural = "11角色表" #verbose_name_plural给你的模型类起一个更可读的名字
    430 
    431 """12标签表"""
    432 class Tag(models.Model):
    433     name =  models.CharField(max_length=64,unique=True) #标签名#CharField定长文本#最长度=64字节#不可以重复
    434     def __str__(self): #__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
    435         return self.name #返回 #标签名
    436     class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
    437         verbose_name_plural =  "12标签表" #verbose_name_plural给你的模型类起一个更可读的名字
    438 
    439 # ————————01PerfectCRM基本配置ADMIN————————
    #models.py

     

      1 {#homework_detail.html#}
      2 {## ————————61PerfectCRM实现CRM学生上传作业————————#}
      3 {% extends 'bpm_master/bpm_sample.html' %}
      4 {% block right-container-content %} {#自定义内容开始 右边页面内容#}
      5     <div class="panel-default">
      6         <div class="panel-body">
      7             <h4>当前用户: {{ request.user }} | 学员名字:{{ request.user.stu_account.name }} |
      8                 学员QQ:{{ request.user.stu_account }}</h4>
      9             <div class="row" style="margin-bottom: 20px">
     10                 <ol class="breadcrumb">
     11                     <li><a href="/bpm/my_course/">我的课程</a></li>
     12                     <li><a href="/bpm/studyrecords/{{ enroll_obj.id }}/">{{ enroll_obj.enrolled_class }}</a></li>
     13                     <li><a href="#">第:{{ studyrecord_obj.course_record.day_num }}节</a></li>
     14                 </ol>
     15             </div>
     16             <h4>作业标题:{{ studyrecord_obj.course_record.homework_title }}</h4>
     17             <h4>作业详情:
     18                 <pre>{{ studyrecord_obj.course_record.homework_content }}</pre>
     19             </h4>
     20             <h4>老师评语:
     21                 <pre>{{ studyrecord_obj.memo }}</pre>
     22             </h4>
     23             <h4>本节成绩: {{ studyrecord_obj.score }} </h4>
     24             <h4>本节作业链接:
     25                 <pre>{{ studyrecord_obj.homework_link }}</pre>
     26             </h4>
     27             <form method="post" class="form-horizontal" role="form">{% csrf_token %}
     28                 <input type="text" class="form-control" name="link" placeholder="作业链接">
     29                 <input type="submit" class="btn btn-info" value="提交">
     30             </form>
     31 
     32 
     33             <hr>
     34             <h4>已经上传的文件: <a id="refresh">刷新</a></h4>
     35             <div class="row">
     36                 <div class="col-xs-9 col-md-6">
     37                     {% for file in file_lists %}
     38                         <div class="right">
     39                             {% for foo in file %}
     40                                 <a>{{ foo }}</a>  |
     41                             {% endfor %}
     42                             <span class="img_f hide">{{ file.0 }}</span>
     43                             <a class="del_img">删除</a>
     44                         </div>
     45                         <br>
     46                     {% endfor %}
     47                 </div>
     48             </div>
     49             <h4>请上传作业</h4>
     50             <form action="{{ request.path }}" method="post" id="dropz" enctype="multipart/form-data"
     51                   class="form-group dropzone">{% csrf_token %}
     52                 <input type="hidden" name="file_id" ng-model="file_id" id="file_id"/>
     53             </form>
     54             <h4>课程大纲:
     55                 <pre>{{ studyrecord_obj.course_record.outline }}</pre>
     56             </h4>
     57         </div>
     58     </div>
     59 {% endblock %}
     60 
     61 
     62 {% block js %}
     63     <script>
     64         //页面加载时绑定按钮点击事件
     65         $("#refresh").click(function () {
     66             window.location.reload();//刷新当前页面.
     67         });
     68 
     69         $('.del_img').click(function () {
     70             s = $(this);
     71             texts = s.parent().children("span").text();
     72             {#        alert(texts);#}
     73             $.ajax({
     74                 url: "{{ requset.path }}",
     75                 type: "post",
     76                 data: {"data": texts},
     77                 headers: {'X-CSRFtoken': $.cookie('csrftoken')},
     78                 success: function (arg) {
     79                     if (arg) {
     80                         alert('删除成功!');
     81                         s.parent('div').addClass('hide');
     82                         {#  #添加样式#隐藏#}
     83                     }
     84                 }
     85             })
     86         });
     87 
     88 
     89         Dropzone.autoDiscover = false;
     90         appElement = document.querySelector('div .inmodal');
     91         myDropzone = new Dropzone("#dropz", {
     92             url: "{{ request.path }}",//文件提交地址
     93             paramName: "file", //默认为file
     94             method: "post",  //也可用put
     95             addRemoveLinks: true,
     96             maxFiles: 1,//一次性上传的文件数量上限
     97             maxFilesize: 2, //文件大小,单位:MB
     98             acceptedFiles: ".zip,.7z", //上传的类型
     99             {#            uploadMultiple: true,#}//上传多个
    100             parallelUploads: 1,//一次上传的文件数量
    101             dictDefaultMessage: '请将作业压缩打包后上传',
    102             dictMaxFilesExceeded: "您最多只能上传1个文件!",
    103             dictResponseError: '文件上传失败!',
    104             dictInvalidFileType: "文件类型只能是*.zip,*.7z。",
    105             dictFallbackMessage: "浏览器不受支持",
    106             dictFileTooBig: "文件过大上传文件最大支持.",
    107             dictRemoveLinks: "删除",
    108             dictCancelUpload: "取消",
    109 
    110 
    111             init: function () {
    112                 this.on("addedfile", function (file) {
    113                     //上传文件时触发的事件
    114                     document.querySelector('div .dz-default').style.display = 'none';
    115                 });
    116                 this.on("success", function (file, data) {
    117                     //上传成功触发的事件
    118                     console.log('ok');
    119                 });
    120                 this.on("error", function (file, data) {
    121                     //上传失败触发的事件
    122                     console.log('fail');
    123                     var message = '';
    124                     //lavarel框架有一个表单验证,
    125                     //对于ajax请求,JSON 响应会发送一个 422 HTTP 状态码,
    126                     //对应file.accepted的值是false,在这里捕捉表单验证的错误提示
    127                     if (file.accepted) {
    128                         $.each(data, function (key, val) {
    129                             message = message + val[0] + ';';
    130                         });
    131                         //控制器层面的错误提示,file.accepted = true的时候;
    132                         alert(message);
    133                     }
    134                 });
    135                 this.on("removedfile", function (file) {
    136                     //删除文件时触发的方法
    137                     document.querySelector('div .dz-default').style.display = 'block';
    138                 });
    139             }
    140         });
    141     </script>
    142 {% endblock %}
    143 {## ————————61PerfectCRM实现CRM学生上传作业————————#}
    {#homework_detail.html#}

     1 {#studyrecords.html#}
     2 {## ————————60PerfectCRM实现CRM学生上课记录————————#}
     3 {% extends 'bpm_master/bpm_sample.html' %}
     4 {% load bpm_tags %}
     5 {% block right-container-content %} {#自定义内容开始 右边页面内容#}
     6     <div class="panel-default">
     7         <div class="panel-body">
     8             <h4>当前用户: {{ request.user }} | 学员名字:{{ request.user.stu_account.name }} |
     9                 学员QQ:{{ request.user.stu_account }}</h4>
    10             <ol class="breadcrumb">
    11                 <li><a href="/bpm/student_course/">我的课程</a></li>
    12                 <li><a href="/bpm/studyrecords/{{ enroll_obj.id }}/">{{ enroll_obj.enrolled_class }}</a></li>
    13             </ol>
    14 
    15             <table class="table table-striped table-responsive ">
    16                 <thead>
    17                 <tr>
    18                     <th>课程节次</th>
    19                     <th>签到状态</th>
    20                     <th>本节作业</th>
    21                     <th>本节成绩</th>
    22                     <th>本节讲师</th>
    23                     <th>上课日期</th>
    24                     <th>本节大纲</th>
    25                     <th>作业标题</th>
    26                     <th>作业要求</th>
    27                 </tr>
    28                 </thead>
    29 
    30 
    31                 <tbody>
    32                 {% for studyrecord in studyrecordlist %}
    33                     <tr>
    34                         <td>{{ studyrecord.course_record.day_num }}</td>
    35                         {#课程节次#}
    36                         <td>{{ studyrecord.get_attendance_display }}</td>
    37                         {#签到状态#}
    38                         <td>
    39                             <a href="{% url 'homework_detail' enroll_obj.id studyrecord.id %}">
    40                                 {{ studyrecord.course_record.has_homework }}
    41                             </a>
    42                         </td>
    43                         {#本节作业#}
    44                         <td>{{ studyrecord.get_score_display }}</td>
    45                         {#本节成绩#}
    46                         <td>{{ studyrecord.course_record.teacher }}</td>
    47                         {#本节讲师#}
    48                         <td>{{ studyrecord.course_record.date }}</td>
    49                         {#上课日期#}
    50                         <td>
    51                             <pre style=" 240px;height: 60px">{{ studyrecord.course_record.outline }}</pre>
    52                             {#本节大纲#}
    53                         </td>
    54                         <td>
    55                             <pre style=" 240px;height: 60px">{{ studyrecord.course_record.homework_title }}</pre>
    56                             {#作业标题#}
    57                         </td>
    58                         <td>
    59                             <pre style=" 240px;height: 60px">{{ studyrecord.course_record.homework_content }}</pre>
    60                             {#作业要求#}
    61                         </td>
    62                     </tr>
    63                 {% endfor %}
    64                 </tbody>
    65             </table>
    66         </div>
    67     </div>
    68 {% endblock %}
    69 {## ————————60PerfectCRM实现CRM学生上课记录————————#}
    {#studyrecords.html#}


     

    如果感觉本章博客对您有帮助,请尽情打赏吧!

  • 相关阅读:
    Python 函数与函数式编程
    Python 字符编码与转码
    Python 读写txt文件操作
    两阶段事务总结
    MPPDB集群高可用设计
    MPPDB中的各个组件
    IntelliJ IDEA2016学习小结
    mysql免安装版配置
    理想的智能机
    java对象的大小
  • 原文地址:https://www.cnblogs.com/ujq3/p/9032335.html
Copyright © 2011-2022 走看看