Django之crm
crm注册
crm注册Form
from django import forms
from crm import models
from django.core.exceptions import ValidationError # ModelForm的作用:做验证,生成form表单input框
class BaseForm(forms.ModelForm):
# 给所有的字段添加属性
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for field in self.fields.values():
field.widget.attrs.update({'class': 'form-control'}) # 注册form
class RegForm(BaseForm):
password = forms.CharField(
# input框前面提示语
label='密码',
# 注册的时候密码为密文
widget=forms.widgets.PasswordInput(),
# 最小长度为6
min_length=6,
# 提示的错误信息
error_messages={'min_length': '最小长度为6'}
)
re_password = forms.CharField(
label='确认密码',
# 注册的时候密码为密文
widget=forms.widgets.PasswordInput()
) class Meta:
model = models.UserProfile
# fields = '__all__' # 所有字段
fields = ['username', 'password', 're_password', 'name', 'department'] # 指定字段
# exclude = ['']
widgets = {
# 给单个的字段添加属性,或者进行设置
'username': forms.widgets.EmailInput(attrs={'class': 'form-control'}),
'password': forms.widgets.PasswordInput,
} # 能让字段在admin中用中文来显示----(和verbose_name作用一样)
labels = {
'username': '用户名',
'password': '密码',
'name': '姓名',
'department': '部门',
} # 提示错误信息,能给页面传递过去并展现出来
error_messages = {
'password': {
'required': '密码不能为空',
}
} # def __init__(self, *args, **kwargs):
# super().__init__(*args, **kwargs)
# for filed in self.fields.values():
# filed.widget.attrs.update({'class': 'form-control'}) # ModelForm的作用:做验证,生成form表单(全局钩子--全局校验就是所有的字段校验一遍,然后再进行二次校验)
def clean(self):
pwd = self.cleaned_data.get('password')
re_pwd = self.cleaned_data.get('re_password')
if pwd == re_pwd:
return self.cleaned_data
self.add_error('re_password', '两次密码不一致')
raise ValidationError('两次密码不一致')
给字段添加属性的不同方式:
for field in self.fields.values():
field.widget.attrs.update({"class":"form-control"}) for field in self.fields:
self.fields[field].widget.attrs.update({"class":"form-control"}) class Meta:
model = models.Permission
widgets = {
"name":forms.widgets.EmailInput(attrs={"class":"form-control"})
crm注册函数
# 注册
def register(request):
# 实例化一个空的注册对象
form_obj = RegForm()
if request.method == 'POST':
# 实例化一个带POST参数的注册对象
form_obj = RegForm(request.POST)
# 进行校验
if form_obj.is_valid():
# 创建新用户
# 方法一
# form_obj.cleaned_data.pop('re_password')
# models.UserProfile.objects.create_user(**form_obj.cleaned_data) # 方法二
obj = form_obj.save()
obj.set_password(obj.password)
obj.save()
return redirect('/login/')
return render(request, 'register.html', {'form_obj': form_obj})
crm登录
def login(request):
err_msg = ''
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
# 把获取到的数据与数据库做校验
obj = auth.authenticate(request, username=username, password=password)
# 如果通过校验,则跳转
if obj:
# 记录登录的用户
auth.login(request, obj)
return redirect(reverse('consumer'))
err_msg = '用户或密码错误'
return render(request, 'login.html', {'err_msg': err_msg})
crm之客户
crm函数
# 进行了深拷贝
query_params = request.GET.copy() # <QueryDict: {'query': ['alex']}> # query_params = request.GET # <QueryDict: {'query': ['alex']}> # _mutable = True就可以修改,经过urlencode()后变为 # query=alex&page=1
query_params._mutable = True query_params.urlencode() # 执行完可以得到以下结果
# query_params['page'] = 1 # <QueryDict: {'query': ['alex'],'page': ['1']}>
# query=alex&page=1
# 判断是否存在这个操作
if not hasattr(self, action):
return HttpResponse('非法操作')
# 通过反射来执行函数
ret = getattr(self, action)()
# 公户变私户
def multi_pri(self):
# 获取选择的数据的ID
ids = self.request.POST.getlist('id')
# 计算出想要放入私户中的个数
pri_num = len(ids) # 用户总数不能超过设置值(在settings做了配置)
if self.request.user.customers.count() + pri_num > settings.CUSTOMER_MAX_NUM:
return HttpResponse('做人不要太贪心,给别人留点机会') # 方法一
# models.Customer.objects.filter(id__in=ids).update(consultant=self.request.user)
# 方法二(这里add中放的必须是对象)
self.request.user.customers.add(*models.Customer.objects.filter(id__in=ids)) # 事务:
with transaction.atomic():
# select_for_update 加锁(行级加锁)
obj_list = models.Customer.objects.filter(id__in=ids, customer__isnull=True).select_for_update() # 如果想要加入的个数还等于获取的个数,则说明可以进行加入,否则就是其中有的已经被别人抢走了
if pri_num == len(obj_list):
obj_list.update(consultant=self.request.user)
else:
return HttpResponse('你手速太慢了,已经被别人抢走了。')
# 查询条件函数
def get_search_contion(self, query_list):
# 从页面上获取query参数,如果没有的话,就默认为空
query = self.request.GET.get('query', '')
# 调用Q方法
q = Q()
q.connector = 'OR' # 意思是Q中存放的条件之间为或者的关系
# q.children.append(Q(('qq__contains', query)))
# q.children.append(Q(('name__contains', query)))
for i in query_list:
q.children.append(Q(('{}__contains'.format(i), query)))
return q
# Q(Q(qq__contains=query) | Q(name__contains=query))
crm新增和编辑客户
# 新增和编辑客户
def consumer(request, edit_id=None): # 新增时,获取的对象为空
obj = models.Customer.objects.filter(id=edit_id).first() # 编辑时需要给传带数据的对象所以需要传instance=obj
form_obj = ConsumerForm(instance=obj) if request.method == 'POST':
# 此时传入的obj为编辑后的数据对象,而且Form中的参数位置不能颠倒
form_obj = ConsumerForm(request.POST, instance=obj) # 对实例化后的对象进行校验
if form_obj.is_valid():
form_obj.save()
# 获取到下一个跳转的地址next
next = request.GET.get('next')
# 如果next存在则跳转到next指向的地址
if next:
return redirect(next)
return redirect(reverse('consumer'))
return render(request, 'crm/consumer.html', {'form_obj': form_obj, 'edit_id': edit_id})
crm跟进记录
# 因为必须要指定销售所以和其他的新增和编辑有区别
obj = models.ConsultRecord.objects.filter(id=edit_id).first() or models.ConsultRecord(consultant=request.user)
crm报名记录
# 修改用户的状态(添加报名表后)
enrollment_obj.customer.status = 'signed'
enrollment_obj.customer.save()
crm课程记录
# 课程记录中的一个功能
def multi_init(self):
# 根据当前提交的课程记录ID批量初始化学生的学习记录
course_ids = self.request.POST.getlist('id')
course_obj_list = models.CourseRecord.objects.filter(id__in=course_ids) for course_obj in course_obj_list:
# 查询当前课程记录代表的班级的学生
all_students = course_obj.re_class.customer_set.filter(status='studying') student_list = [] for student in all_students:
student_list.append(models.StudyRecord(course_record=course_obj, student=student))
# 批量创建对象
models.StudyRecord.objects.bulk_create(student_list)
crm学习记录
from django.forms import modelformset_factory # 展示学习记录
def studylist(request, course_id):
# 生成Django的form表单在页面上能展示出来,能更好的进行编辑修改。extra默认为1
FormSet = modelformset_factory(models.StudyRecord, StudyRecordForm, extra=0)
queryset = models.StudyRecord.objects.filter(course_record_id=course_id)
# 实例化一个对象
form_set = FormSet(queryset=queryset)
if request.method == 'POST':
form_set = FormSet(request.POST)
if form_set.is_valid():
form_set.save()
return render(request, 'crm/study_list.html', {'form_set': form_set})
Django之crm的更多相关文章
- Django之CRM项目Day5-跳转页面 跟进记录 报名记录
1 编辑和添加后跳转页面: 思路:写一个参数将路径的条件带上 注意:捋流程的时候从urls里开始 1.在crm文件夹下新建python包:templatetags,在包里新建url.py: from ...
- Django之CRM项目Day3-客户展示及分页
1.展示客户 模板的查找顺序: 先找全局的templates--> 按照app的注册顺序找templates中的文件 使用admin添加数据: 创建超级用户 python manage.py ...
- Django项目——CRM
一.开发背景 由于公司人员的增多,原来通过excel表格存取方式过于繁琐,而且对于公司人员的调配和绩效考核等不能做到精确处理,所以开发crm系统,开始开发只是针对销售人员和客户,后面陆续加上一些操作, ...
- Django 实现CRM 问卷调查功能组件
目录结构: 母版 {% load staticfiles %} <!DOCTYPE html> <html lang="zh-CN"> <head&g ...
- 使用Django完成CRM管理系统
CRM介绍: CRM即客户关系管理,是指企业用CRM技术来管理与客户之间的关系.在不同场合下,CRM可能是一个管理学术语,可能是一个软件系统.通常所指的CRM,指用计算机自动化分析销售.市场营销.客户 ...
- Django 项目CRM总结
0. 项目说明: 1. 销售自动分配客户资源: 给销售分配权重及承单数量,创建权重表,通过销售权重进行从大到小进行排序 以承单数循环添加到列表,承单数是多少列表添加就添加多少次 考虑到如果服务重启,或 ...
- 源码安装python +NGINX 的坎坷路 +uwsgi安装 部署django 的CRM项目
一.Nginx安装(基于ubuntu17.10 版本) 首先我们是基于源码安装,主要有如下步骤 1.安装依赖包 1.安装gcc g++的依赖库 sudo apt-get install build-e ...
- django - 总结 - CRM - 知识点
1.扩展auth_user from django.contrib.auth.models import User,AbstractUser class UserInfo(AbstractUser): ...
- Django之CRM项目Day6-公私户转换问题解决 班主任功能
1.解决公户转私户的问题 数据库中加锁: begin; 开始事务 select * from user where id=1 for update; 加锁 commit; 结束事务 dja ...
随机推荐
- django for 循环中,获取序号
模板的for循环中,如何获取序号? 想过用enumerate,但是在模板中会报错 Could not parse the remainder xxx: 后来搜到 forloop.counter,完美解 ...
- 机器学习进阶-图像形态学操作-开运算与闭运算 1.cv2.morphologyEx(进行各类形态学变化) 2.op=cv2.MORPH_OPEN(先腐蚀后膨胀) 3.op=cv2.MORPH_CLOSE(先膨胀后腐蚀)
1.cv2.morphologyEx(src, op, kernel) 进行各类形态学的变化 参数说明:src传入的图片,op进行变化的方式, kernel表示方框的大小 2.op = cv2.MO ...
- maven的环境变量配置
一: 首先下载maven, 下载地址:http://maven.apache.org/download.html 打开这个连接:选择File下面的apache-maven-3.2.1-bin.zip链 ...
- Xcode 8 注释快捷键失效
sudo /usr/libexec/xpccachectl 重启
- mui longtap 事件无效
1.mui 的部分事件默认是关闭的 需要在init中单独配置事件开关 mui.init({ gestureConfig: { longtap: true, //默认为false } })
- JAVA 原子操作类
上文中,guava代码中就用到了,在这里再专门捋一下 部分内容源自: https://www.jianshu.com/p/712681f5aecd https://www.yiibai.com/jav ...
- 跨域(二)——WebSocket
严格地说,WebSocket技术不属于HTML5,这个技术是对HTTP无状态连接的一种革新,本质就是一种持久性socket连接,在浏览器客户端通过javascript进行初始化连接后,就可以监听相关的 ...
- Java API下载和查阅方法
使用来自API的类是简单的.只要把它当做自己写的就可以,采用import来引用,可以节省自己编程的气力~ 1.API文档下载地址 https://www.oracle.com/technetwork/ ...
- 查看Linux物理CPU个数
查看内核版本 lsb_release -a 查看物理CPU个数.核数.逻辑CPU个数 (1)具有相同core id的CPU是同一个core的超线程. (2)具有相同physical id的CPU是同一 ...
- CHAR 和VARCHAR的区别
CHAR(10)是不可变长度为10的字符串,占的存储空间始终为10个字符的长度,而VARCHAR(10)是可变长度的字符串,故而可以节省空间.例如:储存"aaaaabbbbb",则 ...