django 批量添加文件 自定义分页 model form form
#新建 。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)