# sales_urls.py
# ————————47PerfectCRM实现CRM客户报名流程————————
from django.conf.urls import url
from bpm.sales import sales_views urlpatterns = [
url(r'^customer/(\d+)/enrollment/$', sales_views.enrollment, name="enrollment"),#客户招生#报名流程一 下一步 # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
url(r'^customer/registration/(\d+)/$', sales_views.stu_registration, name="stu_registration"), # 报名流程二 学员签同合
# ————————48PerfectCRM实现CRM客户报名流程学生合同————————
]
# ————————47PerfectCRM实现CRM客户报名流程————————
# sales_urls.py
# sales_views.py
# ————————47PerfectCRM实现CRM客户报名流程————————
from django.db import IntegrityError #主动捕捉错误信息
from django.shortcuts import render #页面返回
from crm import models #数据库
from bpm.bpm_auxiliary import bpm_forms #自定制 forms
from django.contrib.auth.decorators import login_required# 登陆后页面才能访问 # ————————47PerfectCRM实现CRM客户报名流程————————
from django.core.mail import send_mail
# send_mail的参数分别是 邮件标题,邮件内容,发件箱(settings.py中设置过的那个),收件箱列表(可以发送给多个人),失败静默(若发送失败,报错提示我们)
import random
import datetime # 获取时间#登陆过期
#发送邮件的功能 #验证码#密码
class stmp() :
def __init__(self):
self.emaillist=[] #发送给谁
self.code=None #验证码#密码
def stmps(self,request,email,msg_mail): #传参数#页面,session #邮箱,发送给谁 #内容
self.emaillist.append(email) #将邮箱地址添加到调用Django发送邮件功能
# ——————生成验证码——————
_letter_cases = "abcdefghjkmnpqrstuvwxy" # 小写字母,去除可能干扰的i,l,o,z
_upper_cases = _letter_cases.upper() # 大写字母
_numbers = ''.join(map(str, range(3, 10))) # 数字
chars = ''.join((_letter_cases, _upper_cases, _numbers)) # 变成一条字符串
list = random.sample(chars, 4) # 从一条字符串随机选4个字符变成列表
self.code = ''.join(list) # 列表变字符串
# ——————生成验证码——————
# ——————调用Django发送邮件——————
title= 'PerfectCRM项目自动邮件:%s'%self.code # 邮件标题#防止一样的内容被邮箱屏蔽
send_mail(title, # 邮件标题
msg_mail, # 验证码内容
'perfectcrm@sina.cn', # 发送的邮箱 #根据情况重新配置
self.emaillist, # 接受的邮箱
fail_silently=False, # 静默,抛出异常
)
print('发送邮件成功!没收到要换标题!检查发送邮箱的配置!')
# ——————调用Django发送邮件—————— # ————————47PerfectCRM实现CRM客户报名流程————————
# ————————47PerfectCRM实现CRM客户报名流程———————— #报名填写 销售
@login_required # 登陆后页面才能访问
def enrollment(request,customer_id):
msgs={} #错误信息
customer_obj=models.Customer.objects.get(id=customer_id)#取到客户信息记录 #返回到页面#报名人
consultant_obj=models.UserProfile.objects.get(id=request.user.id)#报名课程顾问 stmp_mail = {} #邮件发送成功
stmpemail = stmp() #实例化发送邮件的功能
email = request.POST.get('email') # 让页面POST提交的值,在页面GET后仍然存在显示
if request.method=="POST":
enroll_form= bpm_forms.EnrollmentForm(request.POST)#获取数据
if enroll_form.is_valid():#表单验证
msg = "http://127.0.0.1:8000/bpm/customer/registration/{enroll_obj_id}/"
try:
enroll_form.cleaned_data['customer']=customer_obj#添加学员对象 记录 #报名人
enroll_form.cleaned_data['consultant'] = consultant_obj#报名课程顾问
enroll_obj=models.Enrollment.objects.create(**enroll_form.cleaned_data)#创建记录
msgs['msg']=msg.format(enroll_obj_id=enroll_obj.id)#报名记录对应的id
except IntegrityError as e:
#取到这条记录
enroll_obj=models.Enrollment.objects.get(customer_id=customer_obj.id,
enrolled_class_id=enroll_form.cleaned_data['enrolled_class'].id)
enroll_form.add_error('__all__','记录已经存在,不能重复创建!')
msgs['msg']=msg.format(enroll_obj_id=enroll_obj.id)#报名记录对应的id
if email:
msg_mail = "http://127.0.0.1:8000/bpm/customer/registration/%s/"%enroll_obj.id
stmpemail.stmps(request, email,msg_mail) # 发送邮件
stmp_mail['ok'] = "邮件已发送成功!" else:
enroll_form= bpm_forms.EnrollmentForm()#modelform表单
return render(request, 'bpm_sales/enrollment.html', locals())
# ————————47PerfectCRM实现CRM客户报名流程———————— # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
#学员合同签定
def stu_registration(request,enroll_id):
enroll_obj=models.Enrollment.objects.get(id=enroll_id)#获取报名记录
customer_form= bpm_forms.CustomerForm(instance=enroll_obj.customer)#生成表单
return render(request,'bpm_sales/stu_registration.html',locals())
# ————————48PerfectCRM实现CRM客户报名流程学生合同————————
# sales_views.py
# forms.py
# ————————47PerfectCRM实现CRM客户报名流程————————
from crm import models #数据库
from django.forms import ModelForm #继承forms自定制
#报名 销售填写
class EnrollmentForm(ModelForm):
def __new__(cls, *args, **kwargs):
for field_name,field_obj in cls.base_fields.items():
field_obj.widget.attrs['class'] = 'form-control'## 前端的样式
return ModelForm.__new__(cls)
class Meta:
model= models.Enrollment
fields= ['enrolled_class']
# ————————47PerfectCRM实现CRM客户报名流程———————— # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
#报名学员填 写
class CustomerForm(ModelForm):
def __new__(cls, *args, **kwargs):
for field_name,field_obj in cls.base_fields.items():
field_obj.widget.attrs['class'] = 'form-control'## 前端的样式
if field_name in cls.Meta.readonly_fields:#如果不可修改
field_obj.widget.attrs['disabled'] = True## 前端的样式 灰色
return ModelForm.__new__(cls) class Meta:
model=models.Customer#客户表
fields='__all__'
exclude=['tags','content','memo','status','referral_from','consult_courses']#排除,不显示
readonly_fields=['qq','consultant','source']#不可修改
# ————————48PerfectCRM实现CRM客户报名流程学生合同————————
# forms.py
{#stu_registration.html#}
{## ————————48PerfectCRM实现CRM客户报名流程学生合同————————#}
{% extends 'bpm_master/bpm_sample.html' %}
{% load bpm_tags %}
{% block right-container-content %} {#自定义内容开始 右边页面内容#}
<div class="container col-lg-7 col-md-offset-2">
<div class="panel panel-warning">
<div class=" panel-heading">
<h3 class="panel-title container">报名入学|信息填写</h3>
</div>
<div class="panel-body "> <!--返回提交函数-->
<form method="post" class="form-horizontal" role="form">{% csrf_token %}
{% for foo in customer_form %}
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">{{ foo.label }}</label>
<div class="col-sm-8">
{{ foo }}
</div>
</div>
{% endfor %}
<hr>
{#返回06学员报名信息表的数据#}
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">所报班级</label>
<div class="col-sm-8">
{{ enroll_obj.enrolled_class }}
</div>
</div>
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">课程费用</label>
<div class="col-sm-8">
{{ enroll_obj.enrolled_class.course.price }}
</div>
</div>
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">开课日期</label>
<div class="col-sm-8">
{{ enroll_obj.enrolled_class.start_date }}
</div>
</div> <div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">合同</label>
<div class="col-sm-10">
<div style="width: 550px">
<pre style="height: 300px">{% render_enrolled_contract enroll_obj %} </pre> <!--tgs-->
</div> </div>
</div>
<div class="form-group">
<div class="col-sm-12">
<input type="checkbox" value="{{ enroll_obj.contract_agreed }}" name="contract_agreed"
checked>
我已经认真阅读完协议并接受所有条款
</div>
</div>
<div class="text-center">
<input type="submit" class="btn btn-info" value="提交">
</div>
</form>
</div>
<div class="panel-footer">
<input type="button" class="btn btn-danger right" value="关闭" onclick="CloseWebPage()">
</div>
</div>
</div>
{% endblock %} {% block js %}
<script>
function CloseWebPage() {
if (confirm("您确定要关闭本页吗?")) {
window.opener = null;
window.open('', '_self');
window.close();
}
else {
}
}
</script>
{% endblock %}
{## ————————48PerfectCRM实现CRM客户报名流程学生合同————————#}
{#stu_registration.html#}
# bpm_tags.py # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
from django import template
register = template.Library() #模板库 #合同格式
@register.simple_tag
def render_enrolled_contract(enroll_obj):#合同格式
if enroll_obj.enrolled_class.contract.template:
return enroll_obj.enrolled_class.contract.template.format(course_name=enroll_obj.enrolled_class,stu_name=enroll_obj.customer.name)
else:
return '' # ————————48PerfectCRM实现CRM客户报名流程学生合同———————— # bpm_tags.py
# bpm_tags.py
# settings.py """
Django settings for PerfectCRM project. Generated by 'django-admin startproject' using Django 2.0.3. For more information on this file, see
https://docs.djangoproject.com/en/2.0/topics/settings/ For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.0/ref/settings/
""" import os # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'atkhzsd7emv4_okn@ynhji)p)qbpuvhq+a7@yx5=chaa0$l_br' # SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True ALLOWED_HOSTS = [] # Application definition INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles', # ————————04PerfectCRM实现King_admin注册功能————————
# 'crm.apps.CrmConfig',
'crm',
# ————————04PerfectCRM实现King_admin注册功能———————— # ————————02PerfectCRM创建ADMIN页面————————
'king_admin',
# ————————02PerfectCRM创建ADMIN页面————————
# ————————38PerfectCRM实现全局账号登录注销————————
'gbacc',
# ————————38PerfectCRM实现全局账号登录注销———————— # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
'bpm',
# ————————48PerfectCRM实现CRM客户报名流程学生合同————————
] MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
] ROOT_URLCONF = 'PerfectCRM.urls' TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
# ————————02PerfectCRM创建ADMIN页面————————
'DIRS': [os.path.join(BASE_DIR, 'templates'),
os.path.join(BASE_DIR, 'king_admin/king_templates'), # ————————03PerfectCRM创建基本数据————————
os.path.join(BASE_DIR, 'DBadd/DBadd_templates'),
# ————————03PerfectCRM创建基本数据————————
# ————————38PerfectCRM实现全局账号登录注销————————
os.path.join(BASE_DIR, 'gbacc/gbacc_templates'),
# ————————38PerfectCRM实现全局账号登录注销———————— # ————————47PerfectCRM实现CRM客户报名流程————————
os.path.join(BASE_DIR, 'bpm/bpm_templates'), ]
# ————————47PerfectCRM实现CRM客户报名流程———————— ,
# ————————02PerfectCRM创建ADMIN页面————————
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
] WSGI_APPLICATION = 'PerfectCRM.wsgi.application' # Database
# https://docs.djangoproject.com/en/2.0/ref/settings/#databases DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
} # Password validation
# https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
] # Internationalization
# https://docs.djangoproject.com/en/2.0/topics/i18n/ # ————————01PerfectCRM基本配置ADMIN————————
#LANGUAGE_CODE = 'en-us' #英文转中文方法
LANGUAGE_CODE = 'zh-Hans'
# ————————01PerfectCRM基本配置ADMIN———————— TIME_ZONE = 'UTC' USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.0/howto/static-files/ STATIC_URL = '/static/' # ————————01PerfectCRM基本配置ADMIN————————
STATICFILES_DIRS = [os.path.join(BASE_DIR,'king_admin/static'),
# ————————01PerfectCRM基本配置ADMIN————————
# ————————38PerfectCRM实现全局账号登录注销————————
os.path.join(BASE_DIR, 'gbacc/static'),
# ————————38PerfectCRM实现全局账号登录注销———————— # ————————47PerfectCRM实现CRM客户报名流程————————
os.path.join(BASE_DIR, 'bpm/static'),]
# ————————47PerfectCRM实现CRM客户报名流程———————— # ————————34PerfectCRM实现CRM自定义用户————————
AUTH_USER_MODEL = 'crm.UserProfile'#使用自定的admin 表单
# ————————34PerfectCRM实现CRM自定义用户———————— # ————————44PerfectCRM实现账号快速注册登陆————————
# send e-mail
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' #email后端
EMAIL_USE_TLS = False #是否使用TLS安全传输协议
EMAIL_USE_SSL = True #是否使用SSL加密,qq企业邮箱要求使用
EMAIL_HOST = 'smtp.sina.cn' #发送邮件的邮箱 的 SMTP服务器 #根据情况重新配置
EMAIL_PORT = 465 #发件箱的SMTP服务器端口 #一般不需要修改465
EMAIL_HOST_USER = 'perfectcrm@sina.cn' #发送邮件的邮箱账号 #根据情况重新配置 #perfectcrm@sina.cn pydjango@sina.cn
EMAIL_HOST_PASSWORD = 'admin123456' #发送邮件的邮箱密码 #根据情况重新配置 # ————————44PerfectCRM实现账号快速注册登陆———————— # ————————46PerfectCRM实现登陆后页面才能访问————————
LOGIN_URL = '/gbacc/gbacc_login/'# login_url 配置 #默认 /accounts/login/ #注意: / (绝对路径)
# ————————46PerfectCRM实现登陆后页面才能访问————————
# settings.py
#models.py # ————————01PerfectCRM基本配置ADMIN———————— from django.db import models
# Create your models here. """
#运行 Terminal
# 生成 数据表
# python manage.py makemigrations
# 数据表 迁移
# python manage.py migrate
""" """01校区表"""
class Branch(models.Model):
name = models.CharField(max_length=128,unique=True) #校区名#CharField作用是保存文本,定长的变量类型
addr = models.CharField(max_length=128) #地址
def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
return self.name #返回 #校区名
class Meta: #通过一个内嵌类 "class Meta" 给你的 model 定义元数据
verbose_name_plural = "01校区表" #verbose_name_plural给你的模型类起一个更可读的名字 """02班级表"""
class ClassList(models.Model):
#ForeignKey就是表与表之间的某种约定的关系 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
branch = models.ForeignKey("Branch",on_delete=models.CASCADE)#校区 关联到 校区表
course = models.ForeignKey("Course",on_delete=models.CASCADE) #课程 关联到 课程表 # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
contract = models.ForeignKey('ContractTemplate', blank=True, null=True, default=1,on_delete=models.CASCADE) # 合同表
# ————————48PerfectCRM实现CRM客户报名流程学生合同———————— class_type_choices = ( #上课形式
(0,'面授(脱产)'),
(1,'面授(周末)'),
(2,'网络班'),)
#PositiveSmallIntegerField正小整数 0 ~ 32767 #choices是Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
class_type = models.SmallIntegerField(choices=class_type_choices)#上课形式 #PositiveSmallIntegerField正小整数 0 ~ 32767
semester = models.PositiveSmallIntegerField(verbose_name="学期") #课程的第几期 #ManyToManyField多对多和外键工作方式相同,只不过我们处理的是QuerySet而不是模型实例。
teachers = models.ManyToManyField("UserProfile") # 老师 关联到 账号表 start_date = models.DateField(verbose_name="开班日期") #DateField 日期格式 YYYY-MM-DD #verbose_name是Admin中显示的字段名称 # DateField 日期格式 YYYY-MM-DD #verbose_name是Admin中显示的字段名称 #Django可空#数据库可以为空
end_date = models.DateField(verbose_name="结业日期",blank=True,null=True) def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
return "%s %s %s" %(self.branch,self.course,self.semester) #返回 #%s格式化输出字符串 #校区#课程# 学期
class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
unique_together=('branch','course','semester') #联合索引
verbose_name_plural = "02班级表" #verbose_name_plural给你的模型类起一个更可读的名字 """03课程表,可以报名那些课程"""
class Course(models.Model):
name = models.CharField(max_length=64,unique=True)#课程名 #CharField作用是保存文本,定长的变量类型
price = models.PositiveSmallIntegerField(verbose_name="学费")#学费#PositiveSmallIntegerField正小整数 0 ~ 32767
period = models.PositiveSmallIntegerField(verbose_name="周期(月)") #PositiveSmallIntegerField正小整数 0 ~ 32767
outline = models.TextField() #课程大纲 #文本类型
def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
return self.name #返回 #课程名
class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
verbose_name_plural = "03课程表"#verbose_name_plural给你的模型类起一个更可读的名字 '''04客户信息表'''
class Customer(models.Model):
name = models.CharField(max_length=32,blank=True,null=True)#客户名#CharField定长文本 #名字最长32 # Django可空 #数据库可以为空
qq = models.CharField(max_length=64,unique=True) #QQ号#CharField定长文本 #名字最长64 #唯一,不能重复
qq_name = models.CharField(max_length=64,blank=True,null=True)#QQ名 #CharField定长文本 #名字最长64 # Django可空 #数据库可以为空
phone = models.CharField(max_length=64,blank=True,null=True)#手机号 #CharField定长文本 #名字最长64 # Django可空 #数据库可以为空 # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
id_num=models.CharField(max_length=64,blank=True,null=True,verbose_name='身份证号')#身份证号
email=models.EmailField(max_length=64,blank=True,null=True,verbose_name='邮箱')#email
sex_choices=((0,'保密'),(1,'男'),(2,'女'))
sex=models.SmallIntegerField(choices=sex_choices,default=0,verbose_name='性别')
# ————————48PerfectCRM实现CRM客户报名流程学生合同———————— source_choices = ( #客户渠道来源 (内存生成)
(0,'转介绍'),
(1,'QQ群'),
(2,'官网'),
(3,'百度推广'),
(4,'51CTO'),
(5,'知乎'),
(6,'市场推广'),)
#PositiveSmallIntegerField正小整数 0 ~ 32767(省空间)#choices是Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
source = models.SmallIntegerField(choices=source_choices)#客户渠道来源 #CharField定长文本#verbose_name是Admin中显示的字段名称#名字最长64 # Django可空 #数据库可以为空
referral_from = models.CharField(verbose_name="转介绍人qq",max_length=64,blank=True,null=True) #来自谁介绍的 #ForeignKey就是表与表之间的某种约定的关系#verbose_name是Admin中显示的字段名称 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
consult_courses = models.ForeignKey("Course",verbose_name="咨询课程", on_delete=models.CASCADE) #关联到 课程表 content= models.TextField(verbose_name="咨询详情") #TextField无限制长度的文本#verbose_name是Admin中显示的字段名称 #ManyToManyField多对多和外键工作方式相同,只不过我们处理的是QuerySet而不是模型实例。
tags = models.ManyToManyField("Tag",blank=True)#多对多关联到 标签表 #ForeignKey就是表与表之间的某种约定的关系 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
consultant = models.ForeignKey("UserProfile", on_delete=models.CASCADE) #关联到 账号表 memo = models.TextField(blank=True,null=True)#备注#TextField无限制长度的文本#Django可空#数据库可以为空 #DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读)
date = models.DateTimeField(auto_now_add=True)#创建时间(数据库自增) def __str__(self): #__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
return self.qq #返回 #QQ号 class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
verbose_name_plural = "04客户表" #verbose_name_plural给你的模型类起一个更可读的名字 # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
#合同模版
class ContractTemplate(models.Model):
name=models.CharField('合同名称',max_length=64,unique=True)
template=models.TextField() def __str__(self):
return self.name
class Meta:
verbose_name_plural='合同表'
# ————————48PerfectCRM实现CRM客户报名流程学生合同———————— """05客户跟进表"""
class CustomerFollowUp(models.Model): #ForeignKey就是表与表之间的某种约定的关系 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
customer = models.ForeignKey("Customer", on_delete=models.CASCADE)#客户名 #关联到 客户信息表 content = models.TextField(verbose_name="跟进内容")#跟进的内容#TextField无限制长度的文本#verbose_name是Admin中显示的字段名称 #ForeignKey就是表与表之间的某种约定的关系 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
consultant =models.ForeignKey("UserProfile", on_delete=models.CASCADE) #关联到 账号表 intention_choices =( #报名状态
(0,'2周内报名'),
(1,'1个月内报名'),
(2,'近期无报名计划'),
(3,'已在其它机构报名'),
(4,'已报名'),
(5,'已拉黑'),)
#PositiveSmallIntegerField正小整数 0 ~ 32767(省空间)#choices是Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
intention=models.SmallIntegerField(choices=intention_choices) #报名状态 #DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读)
date = models.DateTimeField(auto_now_add=True)#创建时间(数据库自增) def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
return "<%s:%s>" %(self.customer.qq,self.intention) #返回#格式化字符串#跨表里的QQ号#报名状态
class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
verbose_name_plural = "05客户跟进表"#verbose_name_plural给你的模型类起一个更可读的名字 """06学员报名信息表"""
class Enrollment(models.Model):
# ForeignKey就是表与表之间的某种约定的关系#verbose_name是Admin中显示的字段名称 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
customer = models.ForeignKey("Customer",on_delete=models.CASCADE)#学员名字 #关联到 客户信息表
enrolled_class = models.ForeignKey("ClassList",verbose_name="所报班级",on_delete=models.CASCADE)#关联到 班级表
consultant = models.ForeignKey("UserProfile",verbose_name="课程顾问",on_delete=models.CASCADE) #关联到 账号表 #BooleanField布尔值类型#default=False默认(True)不允许出现空字符#verbose_name是Admin中显示的字段名称
contract_agreed = models.BooleanField(default=False,verbose_name="学员已经同意合同")#学员看合同
contract_approved = models.BooleanField(default=False,verbose_name="合同已经审核") #谁审核 # DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读)
date = models.DateTimeField(auto_now_add=True)#创建时间(数据库自增) def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
return "%s %s" %(self.customer,self.enrolled_class)#返回#格式化字符串#学员名字#所报班级
class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
unique_together = ("customer","enrolled_class")#联合索引
verbose_name_plural = "06学员报名信息表"#verbose_name_plural给你的模型类起一个更可读的名字 """07缴费记录表"""
class Payment(models.Model):
#ForeignKey就是表与表之间的某种约定的关系#verbose_name是Admin中显示的字段名称 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
customer = models.ForeignKey("Customer",on_delete=models.CASCADE)#学员名字 关联到 客户信息表
course = models.ForeignKey("Course",verbose_name="所报课程",on_delete=models.CASCADE)#关联到 课程表 #PositiveSmallIntegerField正小整数 0 ~ 32767 #verbose_name是Admin中显示的字段名称#默认值=500
amount = models.PositiveIntegerField(verbose_name="数额",default=500)#缴费数额 #ForeignKey就是表与表之间的某种约定的关系#CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
consultant = models.ForeignKey("UserProfile",on_delete=models.CASCADE)#缴费给谁 关联到 账号表 #DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读)
date=models.DateTimeField(auto_now_add=True)#创建时间(数据库自增) def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
return "%s %s" %(self.customer,self.amount)#返回#格式化字符串#学员名字#缴费数额
class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
verbose_name_plural = "07缴费记录表"#verbose_name_plural给你的模型类起一个更可读的名字 """08每节课上课纪录表"""
class CourseRecord(models.Model):
# ForeignKey就是表与表之间的某种约定的关系#verbose_name是Admin中显示的字段名称 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
from_class = models.ForeignKey("ClassList",verbose_name="班级",on_delete=models.CASCADE) #那个班级 #PositiveSmallIntegerField正小整数 0 ~ 32767 #verbose_name是Admin中显示的字段名称
day_num = models.PositiveSmallIntegerField(verbose_name="第几节(天)") #第几节课 # ForeignKey就是表与表之间的某种约定的关系 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
teacher = models.ForeignKey("UserProfile",on_delete=models.CASCADE)#老师是谁 关联到 账号表 #BooleanField布尔值类型#default=True默认(True)不允许出现空字符
has_homework = models.BooleanField(default=True) #有没有作业 # CharField定长文本#名字最长128#Django可空#数据库可以为空
homework_title = models.CharField(max_length=128,blank=True,null=True) #作业标题 #TextField无限制长度的文本#Django可空#数据库可以为空
homework_content = models.TextField(blank=True,null=True) #作业内容 #TextField无限制长度的文本#verbose_name是Admin中显示的字段名称
outline =models.TextField(verbose_name="本节课程大纲") #课程主要讲什么 # DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读)
date = models.DateField(auto_now_add=True)#创建时间(数据库自增) def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
return " %s:%s" %(self.from_class,self.day_num)#返回#格式化字符串#班级#第几节(天)
class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
unique_together = ("from_class","day_num") #联合索引
verbose_name_plural = "08每节课上课纪录表" #verbose_name_plural给你的模型类起一个更可读的名字 """09学习纪录"""
class StudyRecord(models.Model):
# ForeignKey就是表与表之间的某种约定的关系 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
student = models.ForeignKey("Enrollment",on_delete=models.CASCADE)#学生名字 关联到 学员报名信息表
course_record = models.ForeignKey("CourseRecord",on_delete=models.CASCADE)#开课记录 # 关联到 每节课上课纪录表 attendance_choices = (# 本节课上课状态记录
(0,"已签到"),
(1,"迟到"),
(2,"缺勤"),
(3,"早退"),)
#PositiveSmallIntegerField正小整数 0 ~ 32767(省空间)#choices是Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
attendance = models.SmallIntegerField(choices=attendance_choices) # 本节课上课状态记录 score_choices = (#学习成绩
(100,"A+"),
(90,"A"),
(85,"B+"),
(80,"B"),
(75,"B-"),
(70,"C+"),
(65,"C"),
(40,"C-"),
(-20,"D"),
(-50,"COPY"),
(0,"N/A"),)
#PositiveSmallIntegerField正小整数 0 ~ 32767(省空间)#choices是Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
score = models.SmallIntegerField(choices=score_choices) #学习成绩 memo = models.TextField(blank=True,null=True)#TextField无限制长度的文本#Django可空#数据库可以为空 # DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读)
date = models.DateField(auto_now_add=True)#创建时间(数据库自增) def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
return "%s %s %s" % (self.student, self.course_record, self.score)#返回#格式化字符串#学生名字#开课记录#学习成绩
class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
unique_together = ('student','course_record')#联合索引#学生名字#开课记录
verbose_name_plural = "09学习纪录"#verbose_name_plural给你的模型类起一个更可读的名字 # ————————34PerfectCRM实现CRM自定义用户————————
# """10账号表"""
# class UserProfile(models.Model):
# from django.contrib.auth.models import User # 使用django内置的用户表
#
# #OneToOneField一对一 #User是django Admin里的账号表#CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
# user = models.OneToOneField(User,on_delete=models.CASCADE)# 用户名 #创建外键,关联django用户表
#
# name = models.CharField(max_length=32) #账号名(扩展用户字段)#CharField定长文本
#
# #ManyToManyField多对多和外键工作方式相同,只不过我们处理的是QuerySet而不是模型实例。#Django可空
# roles = models.ManyToManyField("Role",blank=True) #角色(权限) # 双向一对多==多对多
#
# def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
# return self.name #返回 #账号名
# class Meta: #通过一个内嵌类 "class Meta" 给你的 model 定义元数据
# verbose_name_plural = "10账号表"#verbose_name_plural给你的模型类起一个更可读的名字
# ————————34PerfectCRM实现CRM自定义用户———————— # ————————34PerfectCRM实现CRM自定义用户————————
#10账号表,创建用户和超级用户
from django.contrib.auth.models import BaseUserManager
class UserProfileManager(BaseUserManager):
def create_user(self, email, name, password=None):
"""
创建并保存一个用户用给定的邮件,日期
出生和密码。
"""
if not email:#没有email 报错
raise ValueError('用户必须有一个电子邮件地址') user = self.model(
email=self.normalize_email(email),#验证邮箱格式
name=name,
)
user.set_password(password)#加密
user.is_active = True
user.save(using=self._db)
return user
def create_superuser(self, email, name, password):
"""
创建并保存一个超级用户具有给定邮件,日期
出生和密码。
"""
user = self.create_user(email,
password=password,
name=name
)
user.is_active = True
user.is_superuser = True
user.save(using=self._db)
return user """10账号表"""
""" #删除数据库 #调用objects = UserProfileManager()#创建账号 #关联这个函数 #运行 Terminal
# 生成 数据表
# python manage.py makemigrations
# 数据表 迁移
# python manage.py migrate
Django Admin里账号密码重置方法
#运行 Terminal
python manage.py createsuperuser Email address: admin@qq.com
用户名 : admin
Password: admin123456
Password (again): admin123456
"""
from django.contrib.auth.models import AbstractBaseUser
# ————————35PerfectCRM实现CRM重写Admin密码修改————————
from django.utils.translation import ugettext_lazy as _ # 语言国际化
from django.utils.safestring import mark_safe
from django.contrib.auth.models import PermissionsMixin
# class UserProfile(AbstractBaseUser):
class UserProfile(AbstractBaseUser,PermissionsMixin):
# ————————35PerfectCRM实现CRM重写Admin密码修改————————
email=models.EmailField(
verbose_name='邮箱账号',
max_length=255,
unique=True#唯一 #登陆账号
)
name=models.CharField(max_length=32,verbose_name='用户名') # ————————35PerfectCRM实现CRM重写Admin密码修改————————
password = models.CharField(_('password'), max_length=128, help_text=mark_safe('''<a href=\"../password/\">修改密码</a>'''))
# ————————35PerfectCRM实现CRM重写Admin密码修改———————— is_active = models.BooleanField(default=True,verbose_name='合法账号')#权限#合法账号
is_superuser = models.BooleanField(default=False,verbose_name='超级账号') #超级账号
objects = UserProfileManager()#创建账号 #关联这个函数
USERNAME_FIELD ='email'#指定做为 #登陆账号
REQUIRED_FIELDS = ['name']#必填字段
def get_full_name(self):
return self.email
def get_short_name(self):
#用户确认的电子邮件地址
return self.email
def __str__(self):
return self.name
def has_perm(self,perm,obj=None):
#指明用户是否被认为活跃的。以反选代替删除帐号。
#最简单的可能的答案:是的,总是
return True #有效 账号
def has_module_perms(self, app_label):
#指明用户是否可以登录到这个管理站点。
# 最简单的可能的答案:是的,总是
return True #职员状态
@property
def is_staff(self):
'''“用户的员工吗?”'''
#最简单的可能的答案:所有管理员都是员工
return self.is_superuser#是不是超级用户状态
# AUTH_USER_MODEL = 'crm.UserProfile'#使用自定的admin 表单 #settings.py
# ————————34PerfectCRM实现CRM自定义用户———————— """11角色表"""
class Role(models.Model):
name = models.CharField(unique=True,max_length=32)#角色名#CharField定长文本#角色名不可以重复#最长度=32字节
def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
return self.name#返回 #角色名
class Meta: #通过一个内嵌类 "class Meta" 给你的 model 定义元数据
verbose_name_plural = "11角色表" #verbose_name_plural给你的模型类起一个更可读的名字 """12标签表"""
class Tag(models.Model):
name = models.CharField(max_length=64,unique=True) #标签名#CharField定长文本#最长度=64字节#不可以重复
def __str__(self): #__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
return self.name #返回 #标签名
class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
verbose_name_plural = "12标签表" #verbose_name_plural给你的模型类起一个更可读的名字 # ————————01PerfectCRM基本配置ADMIN————————
#models.py
#admin.py
# ————————01PerfectCRM基本配置ADMIN————————
from django.contrib import admin
# Register your models here.
from crm import models #从crm导入models # ————————24PerfectCRM实现King_admin自定义操作数据————————
from django.shortcuts import render
# ————————24PerfectCRM实现King_admin自定义操作数据———————— # ————————35PerfectCRM实现CRM重写Admin密码修改————————
from django import forms
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from crm.models import UserProfile
#重写admin
class UserCreationForm(forms.ModelForm):
""" 一个表单来创建新用户。包括所有必需的
字段,加上重复密码。"""
password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
class Meta:
model = UserProfile
fields = ('email', 'name')
def clean_password2(self):
# 检查两个密码条目匹配
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError("密码不匹配")
return password2
def save(self, commit=True):
#保存密码散列的格式提供
user = super(UserCreationForm, self).save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
#重写admin
class UserChangeForm(forms.ModelForm):
"""更新用户的一种形式。包括所有字段
用户,但取代了管理员的密码字段
密码散列显示领域。
"""
password = ReadOnlyPasswordHashField(label="Password",
help_text=("原始密码不存储,所以没有办法看到"
"这个用户的密码,但是你可以改变密码 "
"使用 <a href=\"../password/\">修改密码</a>."))#哈值
class Meta:
model = UserProfile
fields = ('email', 'password', 'name', 'is_active', 'is_superuser')
def clean_password(self):
# 不管用户提供什么,返回初始值。
# 这是在这里,而不是在球场上,因为
# 字段没有对初始值的访问
return self.initial["password"]
#重写admin
class UserProfileAdmin(UserAdmin):#用户类,继承上一个类 UserAdmin
# 单添加和更改用户实例
form = UserChangeForm
add_form = UserCreationForm # 字段用于显示用户模型。
# 这些覆盖定义UserAdmin固定在底座上
# auth.User引用特定字段。
list_display = ('email', 'name','is_active', 'is_superuser', ) #显示字段表头
list_filter = ('is_superuser',) # 过滤器(可以包含ManyToManyField) (注意加 逗号 , )
fieldsets = ( #自定义显示字段
(None, {'fields': ('email','name', 'password')}),
('个人信息', {'fields': ( 'email','name')}),
('用户权限', {'fields': ('is_active','is_superuser','groups','user_permissions')}),#后台显示配置
)
#添加自定义字段
# 覆盖get_fieldsets时使用这个属性创建一个用户。
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('email', 'name', 'password1', 'password2')}
),
)
search_fields = ('email',) #搜索(不能包含CharField)(注意加 逗号 , )
ordering = ('email',) #自定义排序,默认'-id'
filter_horizontal = ('groups','user_permissions', ) #复选框 # 现在注册这个新UserAdmin ,因为我们不在使用Django的内置权限
admin.site.register(UserProfile, UserProfileAdmin)
#注销 原来的 # admin.site.register(models.UserProfile) #10账号表
# ————————35PerfectCRM实现CRM重写Admin密码修改———————— # ————————04PerfectCRM实现King_admin注册功能————————
class CustomerAdmin(admin.ModelAdmin):#定制Djanago admin
list_display = ('id','qq','source','consultant','content','date')#显示字段表头
# ————————11PerfectCRM实现King_admin分页显示条数————————
list_per_page = 2 #分页条数
# ————————11PerfectCRM实现King_admin分页显示条数————————
# ————————16PerfectCRM实现King_admin日期过滤————————
# ————————15PerfectCRM实现King_admin多条件过滤————————
# 过滤器(可以包含ManyToManyField) (注意加 逗号 , )
# list_filter = ('source','consultant','consult_courses',)
list_filter = ('date','source','consultant','consult_courses',)
# ————————15PerfectCRM实现King_admin多条件过滤————————
# ————————16PerfectCRM实现King_admin日期过滤————————
# ————————18PerfectCRM实现King_admin搜索关键字————————
#搜索(不能包含CharField)(注意加 逗号 , )
search_fields = ('name','qq',)
# ————————18PerfectCRM实现King_admin搜索关键字———————— # ————————26PerfectCRM实现King_admin自定义排序————————
ordering = ['-qq'] #自定义排序,默认'-id'
# ————————26PerfectCRM实现King_admin自定义排序———————— # ————————27PerfectCRM实现King_admin编辑复选框————————
filter_horizontal = ('tags',) #复选框
# ————————27PerfectCRM实现King_admin编辑复选框———————— # ————————28PerfectCRM实现King_admin编辑限制————————
readonly_fields = ('qq','consultant',) # 不可修改
# ————————28PerfectCRM实现King_admin编辑限制———————— # ————————24PerfectCRM实现King_admin自定义操作数据————————
# from django.shortcuts import render
actions = ['test_actions',]#定制功能 #测试返回到一个新页面
def test_actions(self,request,arg2):#对应的函数 #request类自己的请求 #arg2类的内容
return render(request,"king_admin/table_index.html")
test_actions.short_description = "测试显示中文"
# ————————24PerfectCRM实现King_admin自定义操作数据————————
# ————————04PerfectCRM实现King_admin注册功能———————— #注册到 Django Admin里
admin.site.register(models.Branch) #01校区表
admin.site.register(models.ClassList) #02班级表
admin.site.register(models.Course) #03课程表,可以报名那些课程 # ————————04PerfectCRM实现King_admin注册功能————————
# admin.site.register(models.Customer) #04客户信息表
admin.site.register(models.Customer,CustomerAdmin) #04客户信息表
# ————————04PerfectCRM实现King_admin注册功能———————— # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
admin.site.register(models.ContractTemplate) #合同模版
# ————————48PerfectCRM实现CRM客户报名流程学生合同———————— admin.site.register(models.CustomerFollowUp) #05客户跟进表
admin.site.register(models.Enrollment) #06学员报名信息表
admin.site.register(models.Payment) #07缴费记录表
admin.site.register(models.CourseRecord) #08每节课上课纪录表
admin.site.register(models.StudyRecord) #09学习纪录 # ————————35PerfectCRM实现CRM重写Admin密码修改————————
# admin.site.register(models.UserProfile) #10账号表
# ————————35PerfectCRM实现CRM重写Admin密码修改———————— admin.site.register(models.Role) #11角色表
admin.site.register(models.Tag) #12标签表 '''
Django Admin里账号密码重置方法
#运行 Terminal python manage.py createsuperuser Username : admin
Email address: admin@qq.com
Password: admin123456
Password (again): admin123456 英文转中文方法
到settings.py里修改
# LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'zh-Hans'
''' # ————————01PerfectCRM基本配置ADMIN————————
#admin.py
#运行 Terminal
# 生成 数据表
# python manage.py makemigrations
# 数据表 迁移
# python manage.py migrate
# DBadd_urls.py
# ————————03PerfectCRM创建基本数据————————
from django.conf.urls import url
from DBadd import auth_views
from DBadd import crm_views urlpatterns = [
url(r'^auth_user/$', auth_views.auth_user), #Django账号表 url(r'^crm_Role/$', crm_views.crm_Role), #角色表 等基本信息
url(r'^crm_UserProfile/$', crm_views.crm_UserProfile),#账号表 #随机学生
url(r'^crm_userprofile_roles/$', crm_views.crm_userprofile_roles),#账号角色关联表 #随机学生 url(r'^crm_Customer/$', crm_views.crm_Customer), # 04客户信息表 # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
url(r'^crm_ContractTemplate/$', crm_views.crm_ContractTemplate), # 角色表 等基本信息
# ————————48PerfectCRM实现CRM客户报名流程学生合同————————
]
# ————————03PerfectCRM创建基本数据————————
# DBadd_urls.py
# crm_views.py # ————————03PerfectCRM创建基本数据———————— from django.shortcuts import render
from django.shortcuts import redirect
from django.shortcuts import HttpResponse from crm import models
from django.contrib.auth import models as auth_models #随机字符串
import random
from random import choice #添加"""基本数据"""
def crm_Role(request):
if request.method == "GET":
user_list = models.Role.objects.all()
return render(request, 'crm_Role.html', {'user_list':user_list})
elif request.method == "POST":
try:
models.Role.objects.create(name='角色学生')
models.Role.objects.create(name='角色销售')
models.Role.objects.create(name='角色老师')
models.Role.objects.create(name='角色校长')
models.Role.objects.create(name='角色系统维护') models.Branch.objects.create(name='北京校区',addr='北京*')
models.Branch.objects.create(name='广东校区',addr='广东东莞市')
models.Branch.objects.create(name='上海校区',addr='上海黄浦江')
models.Branch.objects.create(name='福建校区',addr='福建仙游县')
models.Branch.objects.create(name='四川校区',addr='四川成都市') models.Tag.objects.create(name='好,很好')
models.Tag.objects.create(name='很有兴趣')
models.Tag.objects.create(name='兴趣不大')
models.Tag.objects.create(name='交钱很爽快')
models.Tag.objects.create(name='随便问问的') models.Course.objects.create(name='Pyton',price='',period='',outline='Python , 是一种面向对象的解释型计算机程序设计语言,具有丰富和强大的库,Python 已经成为继JAVA,C++之后的的第三大语言。 特点:简单易学、免费开源、高层语言、可移植性强、面向对象、可扩展性、可嵌入型、丰富的库、规范的代码等。')
models.Course.objects.create(name='PHP',price='',period='',outline='PHP语言是目前Web后端开发使用最广泛的语言,几乎绝大多数网站使用。PHP开发快速,开发成本低,周期短,后期维护费用低,开源产品丰富。')
models.Course.objects.create(name='Java',price='',period='',outline='完成本套餐的学习,学员可以全面掌握后续JavaEE开发所需的Java技术,为后续学习JavaEE开发打下坚实的基础。') # ————————47PerfectCRM实现CRM客户报名流程———————— # models.UserProfile.objects.create(name='ADMIN系统维护', user_id=1)
# models.UserProfile.objects.create(name='李白销售老师', user_id=2)
# models.UserProfile.objects.create(name='杜甫销售老师', user_id=3)
# models.UserProfile.objects.create(name='唐伯虎销售老师', user_id=4)
# models.UserProfile.objects.create(name='颜真卿老师', user_id=5)
# models.UserProfile.objects.create(name='罗贯中老师', user_id=6)
# models.UserProfile.objects.create(name='白居易老师', user_id=7)
# models.UserProfile.objects.create(name='施耐庵老师', user_id=8)
# models.UserProfile.objects.create(name='曹雪芹校长', user_id=9) models.UserProfile.objects.create(last_login='2018-04-18', email='admin@qq.com',name='admin',is_active=1,is_superuser=1,password='pbkdf2_sha256$100000$cCkwdwzBiea6$VNOFkD7HAKwsjKXsDZMOGO8ct3EpVMaX2JPU+h5PK9E=')
models.UserProfile.objects.create(last_login='2018-04-18', email='admin1@qq.com',name='admin1',is_active=1,is_superuser=1,password='pbkdf2_sha256$100000$cCkwdwzBiea6$VNOFkD7HAKwsjKXsDZMOGO8ct3EpVMaX2JPU+h5PK9E=')
models.UserProfile.objects.create(last_login='2018-04-18', email='admin2@qq.com',name='admin2',is_active=1,is_superuser=1,password='pbkdf2_sha256$100000$cCkwdwzBiea6$VNOFkD7HAKwsjKXsDZMOGO8ct3EpVMaX2JPU+h5PK9E=')
models.UserProfile.objects.create(last_login='2018-04-18', email='admin3@qq.com',name='admin3',is_active=1,is_superuser=1,password='pbkdf2_sha256$100000$cCkwdwzBiea6$VNOFkD7HAKwsjKXsDZMOGO8ct3EpVMaX2JPU+h5PK9E=')
models.UserProfile.objects.create(last_login='2018-04-18', email='admin4@qq.com',name='admin4',is_active=1,is_superuser=1,password='pbkdf2_sha256$100000$cCkwdwzBiea6$VNOFkD7HAKwsjKXsDZMOGO8ct3EpVMaX2JPU+h5PK9E=')
models.UserProfile.objects.create(last_login='2018-04-18', email='admin5@qq.com',name='admin5',is_active=1,is_superuser=1,password='pbkdf2_sha256$100000$cCkwdwzBiea6$VNOFkD7HAKwsjKXsDZMOGO8ct3EpVMaX2JPU+h5PK9E=')
models.UserProfile.objects.create(last_login='2018-04-18', email='admin6@qq.com',name='admin6',is_active=1,is_superuser=1,password='pbkdf2_sha256$100000$cCkwdwzBiea6$VNOFkD7HAKwsjKXsDZMOGO8ct3EpVMaX2JPU+h5PK9E=')
models.UserProfile.objects.create(last_login='2018-04-18', email='admin7@qq.com',name='admin7',is_active=1,is_superuser=1,password='pbkdf2_sha256$100000$cCkwdwzBiea6$VNOFkD7HAKwsjKXsDZMOGO8ct3EpVMaX2JPU+h5PK9E=')
models.UserProfile.objects.create(last_login='2018-04-18', email='admin8@qq.com',name='admin8',is_active=1,is_superuser=1,password='pbkdf2_sha256$100000$cCkwdwzBiea6$VNOFkD7HAKwsjKXsDZMOGO8ct3EpVMaX2JPU+h5PK9E=')
models.UserProfile.objects.create(last_login='2018-04-18', email='admin9@qq.com',name='admin9',is_active=1,is_superuser=1,password='pbkdf2_sha256$100000$cCkwdwzBiea6$VNOFkD7HAKwsjKXsDZMOGO8ct3EpVMaX2JPU+h5PK9E=')
# ————————47PerfectCRM实现CRM客户报名流程———————— models.ClassList.objects.create(class_type=1,semester=2,start_date='2018-03-20',branch_id=1,course_id=1)
models.ClassList.objects.create(class_type=0,semester=5,start_date='2018-03-20',branch_id=1,course_id=1)
models.ClassList.objects.create(class_type=2,semester=8,start_date='2018-03-20',branch_id=1,course_id=1)
models.ClassList.objects.create(class_type=0,semester=1,start_date='2018-03-20',branch_id=1,course_id=1)
models.ClassList.objects.create(class_type=1,semester=3,start_date='2018-03-20',branch_id=1,course_id=1)
models.ClassList.objects.create(class_type=0,semester=9,start_date='2018-03-20',branch_id=1,course_id=1)
models.ClassList.objects.create(class_type=2,semester=6,start_date='2018-03-20',branch_id=1,course_id=1)
models.ClassList.objects.create(class_type=1,semester=20,start_date='2018-03-20',branch_id=1,course_id=1)
models.ClassList.objects.create(class_type=0,semester=32,start_date='2018-03-20',branch_id=1,course_id=1) except:
return HttpResponse('基本数据已经添加了。。。') return redirect('/DBadd/crm_Role/') #添加"""10账号表""" #随机学生
def crm_UserProfile(request):
if request.method == "GET":
user_list = models.UserProfile.objects.all()
return render(request, 'crm_UserProfile.html', {'user_list':user_list})
elif request.method == "POST":
for i in range(50): Rword = ''.join(''.join([chr(random.randint(0x4E00, 0x9FBF)) for i in range(3)]).split())# 随机中文
n=Rword a = models.UserProfile.objects.values("user_id").all()
e = auth_models.User.objects.values("id").all()
print('eeeee', e, type(e))
x=e.difference(a)
# for i in x:
# print('zzz', x, type(x)) l=[]
for i in x:
l.append(i['id'])
print('llll', l, type(l)) if len(l)==0:
return HttpResponse('请添加 admin的用户后,再来添加。。。')
else:
c = choice(l)
u = c
models.UserProfile.objects.create(name=n, user_id=u)
return redirect('/DBadd/crm_UserProfile/') #添加"""10账号表--11角色表""" #随机学生
def crm_userprofile_roles(request):
if request.method == "GET":
user_list = models.UserProfile.objects.all()
role_list = models.Role.objects.get(id=1)
return render(request, 'crm_userprofile_roles.html', {'user_list':user_list,'role_list':role_list})
elif request.method == "POST":
try:
for i in range(50):
b1 = models.Role.objects.get(id=1)
a=b1.userprofile_set.values("id").all() e = models.UserProfile.objects.values("id").all()
x = e.difference(a) l = []
for i in x:
l.append(i['id'])
print('llll', l, type(l)) if len(l) == 0:
return HttpResponse('请添加 数据 后,再来添加。。。')
else:
c = choice(l)
print('c', c, type(c)) g1 = models.UserProfile.objects.get(id=c)
b1 = models.Role.objects.get(id=1)
g1.roles.add(b1)
return redirect('/DBadd/crm_userprofile_roles/')
except:
return HttpResponse('没有数据了。。。') # 添加"""04客户信息表"""
def crm_Customer(request):
if request.method == "GET":
user_list = models.Customer.objects.all()
return render(request, 'crm_Customer.html', {'user_list': user_list})
elif request.method == "POST":
for i in range(50):
Rword = ''.join(''.join([chr(random.randint(0x4E00, 0x9FBF)) for i in range(3)]).split()) # 随机中文
r=random.randint(5,18)
Num = "".join(random.choice("") for i in range(r)) # 随机数字 #保证qq的唯一性
Cnum = "".join(random.choice("") for i in range(1)) # 随机数字 #id 不能选择0
try:
models.Customer.objects.create(name=Rword, qq=Num, qq_name=Rword, phone=Num, source=1,
referral_from=Rword, consult_courses_id=1, content=Rword,
consultant_id=Cnum, memo=Rword, date='2018-03-20')
except:
return HttpResponse('数据重复了。。。') return redirect('/DBadd/crm_Customer/') # ————————03PerfectCRM创建基本数据———————— # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
def crm_ContractTemplate(request):
if request.method == "GET":
user_list = models.ContractTemplate.objects.all()
return render(request, 'crm_ContractTemplate.html', {'user_list':user_list})
elif request.method == "POST":
try:
t= '''
委托方:__{stu_name}__
法定代表人或负责人:__{stu_name}__
服务方:_______
法定代表人或负责人:_________
根据《*合同法》的有关规定,经双方当事人协商一致,签订本
合同。
第一条 项目名称__{course_name}__。
(注:本参考格式适用于下列技术服务活动:进行设计、工艺、制造、试验以
及农作物育种,畜禽的饲养等方面的技术指导、讲解技术资料、解决和解答技术问
题;进行示范操作;传授计算机软件的编制技术、先进仪器设备的装配,使用技术
等等。)
第二条 培训的内容和要求:_______。
第三条 培训计划、进度、期限:_______。
第四条 培训地点和方式:____________。
第五条 服务方(教师)的资历和水平:________。
第六条 学员的人数和质量:___________。
第七条 教员、学员的食宿、交通、医疗费用的支付和安排____。
第八条 报酬及其支付方式:__________。
第九条 委托方的违约责任:_________。
1.委托方未按合同提供培训条件,影响合同履行的,约定的报酬仍应如数支
付;
2.擅自将服务方要求保密的技术资料引用、发表和提供给第三方,应支付数
额为____的违约金;
第十条 服务方的违约责任:
1.服务方未按合同制订培训计划,影响培训工作质量的,应当减收___%
的报酬;
2.服务方提供的师资不符合合同要求,服务方有义务予以重新配备;未按合
同规定完成培训工作的,应免收报酬。
第十一条 保密条款:________
当事人双方应对下列技术资料承担保密义务:______。
第十二条 有关技术成果归属条款
在履行合同过程中,服务方利用委托方提供的技术资料和工作条件所完成的新
的技术成果,属于服务方;委托方利用服务方的工作成果所完成的新技术成果,属
于委托方。对新的技术成果享有就该技术成果取得的精神权利(如获得奖金、奖章、
荣誉证书的权利)、经济权利(如专利权、非专利技术的转让权,使用权等)和
其它利益。
第十三条 本合同争议的解决办法:______。
本合同自双方当事人签字、盖章后生效。
委托方负责人(或授权代表) 服务方负责人(或授权代表)
签字:__{stu_name}__(盖章) 签名:____(盖章)
签字时间:_________ 签字时间:_________
签字地点:_________ 签字地点:_________
开户银行:_________ 开户银行:_________
帐号:___________ 帐号:___________
委托方担保人(名称):___ 服务方担保人(名称):___
地址:___________ 地址:___________
负责人(或授权代表) 负责人(或授权代表)
签字:________(盖章) 签字:________(盖章)
签字时间:_________ 签字时间:_________
签字地点:_________ 签字地点:_________
开户银行:_________ 开户银行:_________
帐号:___________ 帐号:___________''' models.ContractTemplate.objects.create(name='技术合同:专业技术培训协议',template=t)
except:
return HttpResponse('数据错误!重复了吧。。。') return redirect('/DBadd/crm_ContractTemplate/') # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
# crm_views.py
{#crm_ContractTemplate.html#}
{## ————————48PerfectCRM实现CRM客户报名流程学生合同————————#}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h3>添加合同</h3> <form method="POST" action="/DBadd/crm_ContractTemplate/">
{% csrf_token %}
<input type="submit"value="添加"/>
</form> <h3>合同详细</h3>
<ul>
{% for row in user_list %}
<li> <a>{{row.id}}-{{row.name}}</a>
<hr>
<pre>{{row.template}}</pre>
</li>
{% endfor %}
</ul> </body>
</html> {## ————————48PerfectCRM实现CRM客户报名流程学生合同————————#}
{#crm_ContractTemplate.html#}
http://127.0.0.1:8000/DBadd/crm_ContractTemplate/
http://127.0.0.1:8000/bpm/customer/registration/1/
Django项目:CRM(客户关系管理系统)--58--48PerfectCRM实现CRM客户报名流程学生合同的更多相关文章
-
Django项目:CRM(客户关系管理系统)--62--52PerfectCRM实现CRM客户报名流程学生合同审核
# sales_urls.py # ————————47PerfectCRM实现CRM客户报名流程———————— from django.conf.urls import url from bpm. ...
-
Django项目:CRM(客户关系管理系统)--61--51PerfectCRM实现CRM客户报名流程学生合同上传照片
# sales_views.py # ————————47PerfectCRM实现CRM客户报名流程———————— from django.db import IntegrityError # 主动 ...
-
Django项目:CRM(客户关系管理系统)--60--50PerfectCRM实现CRM客户报名流程学生合同URL随机码
# sales_urls.py # ————————47PerfectCRM实现CRM客户报名流程———————— from django.conf.urls import url from bpm. ...
-
Django项目:CRM(客户关系管理系统)--84--74PerfectCRM实现CRM权限和权限组限制访问URL
#models.py # ————————01PerfectCRM基本配置ADMIN———————— from django.db import models # Create your models ...
-
Django项目:CRM(客户关系管理系统)--85--75PerfectCRM实现CRM扩展权限
# sales_urls.py # ————————47PerfectCRM实现CRM客户报名流程———————— from django.conf.urls import url from bpm. ...
-
Django项目:CRM(客户关系管理系统)--82--72PerfectCRM实现CRM动态菜单和角色
#models.py # ————————01PerfectCRM基本配置ADMIN———————— from django.db import models # Create your models ...
-
Django项目:CRM(客户关系管理系统)--81--71PerfectCRM实现CRM项目首页
{#portal.html#} {## ————————46PerfectCRM实现登陆后页面才能访问————————#} {#{% extends 'king_admin/table_index.h ...
-
Django项目:CRM(客户关系管理系统)--70--60PerfectCRM实现CRM学生上课记录
#urls.py """PerfectCRM URL Configuration The `urlpatterns` list routes URLs to views. ...
-
Django项目:CRM(客户关系管理系统)--78--68PerfectCRM实现CRM业务流程(bpm)报名缴费分页
# pagination.py # ————————68PerfectCRM实现CRM业务流程(bpm)报名缴费分页———————— from django.utils.safestring impo ...
随机推荐
-
【云计算】Dockerfile示例模板
Dockerfile FROM debian:jessie MAINTAINER "Konrad Kleine" USER root ####################### ...
-
iOS 关于objectForKey返回类型是不是mutable
以前看NSUserDefault时,记住了那里的objectForKey返回的一定是immutable的对象.现在有点弄混了,其实,NSObject的objectForKey方法没有这个限制,是可以返 ...
-
Action Filters for ASP.NET MVC
本文主要介绍ASP.NET MVC中的Action Filters,并通过举例来呈现其实际应用. Action Filters 可以作为一个应用,作用到controller action (或整个co ...
-
用R语言做数据清理(详细教程)
数据的清理 如同列夫托尔斯泰所说的那样:“幸福的家庭都是相似的,不幸的家庭各有各的不幸”,糟糕的恶心的数据各有各的糟糕之处,好的数据集都是相似的.一份好的,干净而整洁的数据至少包括以下几个要素: 1. ...
-
详解intellij idea搭建SSM框架(spring+maven+mybatis+mysql+junit)(上)
SSM(Spring+SpringMVC+MyBatis)框架集由Spring.SpringMVC.MyBatis三个开源框架整合而成,常作为数据源较简单的web项目的框架. 其中spring是一个轻 ...
-
qhfl-9 微信模板消息推送
开发中用的是测试号 微信公众号认证流程 用户登陆 <!DOCTYPE html> <html lang="en"> <head> <met ...
-
vue初学:基础概念
一.vue使用步骤: 1.引包vue.js 2.html中写要操作的DOM节点 3.创建vue对象:new Vue({options}); 4.配置options:el:(要操作的对象,用选择器,同j ...
-
JAVA将list转化为xml文件
pojo类: public class TreeNode { private int id; private String nodeId; private String parentId; priva ...
-
codeforces 814 C. An impassioned circulation of affection 【尺取法 or DP】
//yy:因为这题多组数据,DP预处理存储状态比每次尺取快多了,但是我更喜欢这个尺取的思想. 题目链接:codeforces 814 C. An impassioned circulation of ...
-
Swift_继承
Swift_继承 点击查看源码 func testInheritance() { //基类 class Base { var count = 0.0 var description: String { ...