#新建 。py文件
import os
if __name__ == '__main__':
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "NBcrm.settings")
#manage 文件中的 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "NBcrm.settings")
import django
django.setup()
from nbapp import models
import random
l1 = []
for i in range(1,101):
obj = models.Customer(
qq = ''.join([str(i) for i in random.choices(range(1,10),k=11)]),
name = 'lihua'+ str(i),
sex = random.choice(['male','female']),
source = random.choice(['qq','referral','website']),
course=random.choice(['LinuxL','PythonFullStack']),
)
l1.append(obj)
models.Customer.objects.bulk_create(l1)
#自定义分页 .py文件
#官方推荐,页码数为奇数
class PageNation:
def __init__(self,base_url,current_page_num,total_counts,per_page_counts=10,page_number=5):
'''
:param base_url: 分页展示信息的基础路径
:param current_page_num: 当前页页码
:param total_counts: 总的数据量
:param per_page_counts: 每页展示的数据量
:param page_number: 显示页码数
'''
self.base_url = base_url
self.current_page_num = current_page_num
self.total_counts = total_counts
self.per_page_counts = per_page_counts
self.page_number = page_number
try:
self.current_page_num = int(self.current_page_num)
except Exception:
self.current_page_num = 1
half_page_range = self.page_number // 2
# 计算总页数
self.page_number_count, a = divmod(self.total_counts, self.per_page_counts)
if self.current_page_num < 1:
self.current_page_num = 1
if a:
self.page_number_count += 1
if self.current_page_num > self.page_number_count:
self.current_page_num = self.page_number_count
if self.page_number_count <= self.page_number:
self.page_start = 1
self.page_end = self.page_number_count
else:
if self.current_page_num <= half_page_range:
self.page_start = 1
self.page_end = page_number
elif self.current_page_num + half_page_range >= self.page_number_count:
self.page_start = self.page_number_count - self.page_number + 1
self.page_end = self.page_number_count
else:
self.page_start = self.current_page_num - half_page_range
self.page_end = self.current_page_num + half_page_range
#数据切片依据,起始位置
@property
def start_num(self):
start_num = (self.current_page_num - 1) * self.per_page_counts
return start_num
#数据切片依据,终止位置
@property
def end_num(self):
end_num = self.current_page_num * self.per_page_counts
return end_num
# 拼接HTMl标签
def page_html(self):
tab_html = ''
tab_html += '<nav aria-label="Page navigation" class="pull-right"><ul class="pagination">'
# 上一页
if self.current_page_num == 1:
previous_page = '<li disabled><a href="#" aria-label="Previous" ><span aria-hidden="true">«</span></a></li>'
else:
previous_page = '<li><a href="{0}?page={1}" aria-label="Previous" ><span aria-hidden="true">«</span></a></li>'.format(
self.base_url, self.current_page_num - 1)
tab_html += previous_page
for i in range(self.page_start, self.page_end + 1):
if self.current_page_num == i:
one_tag = '<li class="active"><a href="{0}?page={1}">{1}</a></li>'.format(self.base_url, i)
else:
one_tag = '<li><a href="{0}?page={1}">{1}</a></li>'.format(self.base_url, i)
tab_html += one_tag
# 下一页
if self.current_page_num == self.page_number_count:
next_page = '<li disabled><a href="#" aria-label="Next"><span aria-hidden="true">»</span></a></li>'
else:
next_page = '<li><a href="{0}?page={1}" aria-label="Next"><span aria-hidden="true">»</span></a></li>'.format(self.base_url, self.current_page_num + 1)
tab_html += next_page
tab_html += '</ul></nav>'
return tab_html
#函数low鸡版
def pagenation(base_url,current_page_num,total_counts,per_page_counts=10,page_number=5):
'''
total_counts数据总数
per_page_counts每页分多少条数据
page_number = 页码显示多少个
current_page_num 当前页
:return:
'''
# all_objs_list = models.Customer.objects.all()
# total_counts = all_objs_list.count()
# page_number = 5
try:
current_page_num = int(current_page_num)
except Exception:
current_page_num = 1
half_page_range = page_number//2
#计算总页数
page_number_count,a = divmod(total_counts,per_page_counts)
if current_page_num < 1:
current_page_num = 1
if a:
page_number_count += 1
if current_page_num > page_number_count:
current_page_num = page_number_count
start_num = (current_page_num - 1) * 10
end_num = current_page_num * 10
if page_number_count <= page_number:
page_start = 1
page_end = page_number_count
else:
if current_page_num <= half_page_range:
page_start = 1
page_end = page_number
elif current_page_num + half_page_range >= page_number_count:
page_start = page_number_count - page_number + 1
page_end = page_number_count
else:
page_start = current_page_num - half_page_range
page_end = current_page_num + half_page_range
#拼接HTMl标签
tab_html = ''
tab_html += '<nav aria-label="Page navigation"><ul class="pagination">'
#上一页
if current_page_num == 1:
previous_page = '<li disabled><a href="#" aria-label="Previous" ><span aria-hidden="true">«</span></a></li>'
else:
previous_page = '<li><a href="{0}?page={1}" aria-label="Previous" ><span aria-hidden="true">«</span></a></li>'.format(base_url,current_page_num-1)
tab_html += previous_page
for i in range(page_start,page_end+1):
if current_page_num == i:
one_tag = '<li class="active"><a href="{0}?page={1}">{1}</a></li>'.format(base_url,i)
else:
one_tag = '<li><a href="{0}?page={1}">{1}</a></li>'.format(base_url, i)
tab_html += one_tag
#下一页
if current_page_num == page_number_count:
next_page = '<li disabled><a href="#" aria-label="Next"><span aria-hidden="true">»</span></a></li>'
else:
next_page = '<li><a href="{0}?page={1}" aria-label="Next"><span aria-hidden="true">»</span></a></li>'.format(base_url,current_page_num+1)
tab_html+=next_page
tab_html += '</ul></nav>'
return tab_html,start_num,end_num
#视图函数
def test(request):
wd = request.GET.get('wd','')
condition = request.GET.get('condition','')
print(wd) #小
print(condition+'__contains') #name
condition = condition+'__contains'
#condition: name
current_page_num = request.GET.get('page', 1)
# get:condition=qq&wd=1&page=2
#<QueryDict: {'condition': ['qq'], 'wd': ['1'], 'page': ['2']}> #condition=qq&wd=1&page=2
if wd:
# all_data = models.Customer.objects.filter(Q(qq__contains=wd)|Q(name__contains=wd))
q = Q()
q.connector = 'or' #指定条件连接符号
q.children.append((condition,wd)) #默认是and的关系
q.children.append(('qq_name__contains','小'))
# all_data = models.Customer.objects.filter(name__contains=wd)
all_data = models.Customer.objects.filter(q)
else:
all_data = models.Customer.objects.all()
per_page_counts = 10 #每页显示10条
page_number = 7 #总共显示5个页码
total_count = all_data.count()
# ret_html,start_num,end_num = page.pagenation(request.path, current_page_num,total_count,per_page_counts,page_number)
p_obj = page.PageNation(request.path, current_page_num,total_count,request,per_page_counts,page_number)
ret_html = p_obj.page_html()
all_data = all_data[p_obj.start_num:p_obj.end_num]
return render(request,'test.html',{'all_data':all_data,'ret_html':ret_html})
#html
{{ ret_html|safe }}
page 到 ret 到 HTML
p_obj = page.PageNation(request.path, current_page_num,total_count,request,per_page_counts,page_number) 实例化
ret_html = p_obj.page_html() page 中 类的方法
{{ ret_html|safe }}
#modelform 绑定样式
def __init__(self,*args,**kwargs):
super().__init__(*args,**kwargs)
# print(self.fields)
from multiselectfield.forms.fields import MultiSelectFormField
for field in self.fields.values():
if not isinstance(field,MultiSelectFormField):
field.widget.attrs.update({
'class':'form-control',
})
#form 绑定样式
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for field in self.fields:
self.fields[field].widget.attrs.update({
'class': 'form-control'
})
#例子
import re
from nbapp import models
from django import forms
from django.forms import widgets
from django.core.exceptions import ValidationError
class UserForm(forms.Form):
# input name='username' 'username':'chao' errors.append('错误')
username = forms.CharField(max_length=32, min_length=6, label='用户名',error_messages={'required': '这个字段必须填写!', 'max_length': '最大不能超过32位','min_length': '最小不能低于6位'}, )
password = forms.CharField(max_length=32, min_length=6, label='密码',
error_messages={'required': '这个字段必须填写!', 'max_length': '最大不能超过32位','min_length': '最小不能低于6位'},
widget=widgets.PasswordInput
)
r_password = forms.CharField(max_length=32, min_length=6, label='重复密码',
error_messages={'required': '这个字段必须填写!', 'max_length': '最大不能超过32位','min_length': '最小不能低于6位'},
widget=widgets.PasswordInput)
email = forms.EmailField(max_length=32, label='邮箱',error_messages={'required': '这个字段必须填写!', 'max_length': '最大不能超过32位', 'invalid': '邮箱格式不对'}, )
def clean_username(self):
val = self.cleaned_data.get('username')
user_obj = models.UserInfo.objects.filter(username=val).first()
if user_obj:
raise ValidationError('该用户名已经存在,请换个名字!')
else:
return val
def clean_password(self):
val = self.cleaned_data.get('password')
if val.isdecimal():
raise ValidationError('密码不能为纯数字')
else:
return val
def clean_email(self):
val = self.cleaned_data.get('email')
if re.search('\w+@163.com$', val):
return val
else:
raise ValidationError('必须是163网易邮箱!')
def clean(self):
password = self.cleaned_data.get('password')
r_password = self.cleaned_data.get('r_password')
if password != r_password:
self.add_error('r_password', '两次密码不一致')
else:
return self.cleaned_data
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for field in self.fields:
self.fields[field].widget.attrs.update({
'class': 'form-control'
})
#models中
class Customer(models.Model):
"""
客户表(最开始的时候大家都是客户,销售就不停的撩你,你还没交钱就是个客户)
"""
qq = models.CharField(verbose_name='QQ', max_length=64, unique=True, help_text='QQ号必须唯一')
qq_name = models.CharField('QQ昵称', max_length=64, blank=True, null=True)
name = models.CharField('姓名', max_length=32, blank=True, null=True, help_text='学员报名后,请改为真实姓名')
sex_type = (('male', '男'), ('female', '女'))
sex = models.CharField("性别", choices=sex_type, max_length=16, default='male', blank=True, null=True) #存的是male或者female,字符串
birthday = models.DateField('出生日期', default=None, help_text="格式yyyy-mm-dd", blank=True, null=True)
phone = models.CharField('手机号', blank=True, null=True,max_length=32)
# phone = models.CharField('手机号', blank=True, null=True)
source = models.CharField('客户来源', max_length=64, choices=source_type, default='qq')
introduce_from = models.ForeignKey('self', verbose_name="转介绍自学员", blank=True, null=True) #self指的就是自己这个表,和下面写法是一样的效果
# introduce_from = models.ForeignKey('Customer', verbose_name="转介绍自学员", blank=True, null=True,on_delete=models.CASCADE)
course = MultiSelectField("咨询课程", choices=course_choices,null=True,blank=True) #多选,并且存成一个列表的格式
# course = models.CharField("咨询课程", choices=course_choices) #如果你不想用上面的多选功能,可以使用Charfield来存
class_type = models.CharField("班级类型", max_length=64, choices=class_type_choices, default='fulltime')
customer_note = models.TextField("客户备注", blank=True, null=True, )
status = models.CharField("状态", choices=enroll_status_choices, max_length=64, default="unregistered",help_text="选择客户此时的状态") #help_text这种参数基本都是针对admin应用里面用的
date = models.DateTimeField("咨询日期", auto_now_add=True)
last_consult_date = models.DateField("最后跟进日期", auto_now_add=True) #考核销售的跟进情况,如果多天没有跟进,会影响销售的绩效等
next_date = models.DateField("预计再次跟进时间", blank=True, null=True) #销售自己大概记录一下自己下一次会什么时候跟进,也没啥用
#用户表中存放的是自己公司的所有员工。
consultant = models.ForeignKey('UserInfo', verbose_name="销售", blank=True, null=True)
#form中
class CustomerModelForm(forms.ModelForm):
class Meta:
model = models.Customer
fields = '__all__'
def __init__(self,*args,**kwargs):
super().__init__(*args,**kwargs)
# print(self.fields)
from multiselectfield.forms.fields import MultiSelectFormField
for field in self.fields.values():
if not isinstance(field,MultiSelectFormField):
field.widget.attrs.update({
'class':'form-control',
})
#views中
#获取公户所有客户信息
# def customers(request):
class CustomerView(View):
def get(self,request):
wd = request.GET.get('wd','')
condition = request.GET.get('condition','')
#这是过滤公户的,也就是没有销售的
all_customers = models.Customer.objects.filter(consultant__isnull=True)
if wd:
q = Q()
# q.connector = 'or'
# q.children.append((condition,wd))
q.children.append((condition,wd))
#根据用户查询条件再次进行筛选
all_customers = all_customers.filter(q)
current_page_num = request.GET.get('page',1)
per_page_counts = 5
page_number = 11
total_count = all_customers.count()
page_obj = page.PageNation(request.path,current_page_num,total_count,request,per_page_counts,page_number)
all_customers = all_customers.order_by('-pk')[page_obj.start_num:page_obj.end_num]
ret_html = page_obj.page_html()
return render(request,'customers.html',{'all_customers':all_customers,'ret_html':ret_html})
def post(self,request):
print(request.POST)
self.data = request.POST.getlist('selected_id')
action = request.POST.get('action') #'batch_delete'
if hasattr(self,action):
func = getattr(self,action)
if callable(func):
func(request)
return redirect('customers')
else:
return HttpResponse('不要搞事!!')
else:
return HttpResponse('不要搞事!!')
#批量删除
def batch_delete(self,request):
models.Customer.objects.filter(pk__in=self.data).delete()
#批量更新
def batch_update(self,request):
models.Customer.objects.filter(pk__in=self.data).update(name='雄哥')
#批量公户转私户
def batch_reverse_gs(self,request):
models.Customer.objects.filter(pk__in=self.data).update(consultant=request.user)
# # 批量公户转私户
# def batch_reverse_sg(self, request):
# models.Customer.objects.filter(pk__in=self.data).update(consultant=request.user)
#HTML文件中g
#获取公户所有客户信息
# def customers(request):
class CustomerView(View):
def get(self,request):
wd = request.GET.get('wd','')
condition = request.GET.get('condition','')
#这是过滤公户的,也就是没有销售的
all_customers = models.Customer.objects.filter(consultant__isnull=True)
if wd:
q = Q()
# q.connector = 'or'
# q.children.append((condition,wd))
q.children.append((condition,wd))
#根据用户查询条件再次进行筛选
all_customers = all_customers.filter(q)
current_page_num = request.GET.get('page',1)
per_page_counts = 5
page_number = 11
total_count = all_customers.count()
page_obj = page.PageNation(request.path,current_page_num,total_count,request,per_page_counts,page_number)
all_customers = all_customers.order_by('-pk')[page_obj.start_num:page_obj.end_num]
ret_html = page_obj.page_html()
return render(request,'customers.html',{'all_customers':all_customers,'ret_html':ret_html})
def post(self,request):
print(request.POST)
self.data = request.POST.getlist('selected_id')
action = request.POST.get('action') #'batch_delete'
if hasattr(self,action):
func = getattr(self,action)
if callable(func):
func(request)
return redirect('customers')
else:
return HttpResponse('不要搞事!!')
else:
return HttpResponse('不要搞事!!')
#批量删除
def batch_delete(self,request):
models.Customer.objects.filter(pk__in=self.data).delete()
#批量更新
def batch_update(self,request):
models.Customer.objects.filter(pk__in=self.data).update(name='雄哥')
#批量公户转私户
def batch_reverse_gs(self,request):
models.Customer.objects.filter(pk__in=self.data).update(consultant=request.user)
# # 批量公户转私户
# def batch_reverse_sg(self, request):
# models.Customer.objects.filter(pk__in=self.data).update(consultant=request.user)