Django - CRM项目(4)- 批量创建学生记录、基于modelformset录入成绩、统计成单量
一、crm项目
需求:
1、批量创建学生学习记录
2、基于modelformset组件实现录入学生成绩
3、实现统计各个销售的成单量(借助highcharts或echarts显示)
二、modelformset组件
常用于批量处理多个form表单。使用示例如下:
1、引入modelformset的工厂函数
from django.forms.models import modelformset_factory
2、定义对应的modelform
# 录入成绩校验 class InputSSRecordModelForm(forms.ModelForm): class Meta: model=StudentStudyRecord fields=['score', 'homework_note'] # 校验的字段,要对应页面上可编辑的字段
3、视图函数:
# 录入成绩:基于modelformset组件 from django.forms.models import modelformset_factory class InputScoreView(View): # get请求显示且可编辑 def get(self, request, csRecord_id): # 给modelformset_factory传入一个model和form得一个类model_formset_cls model_formset_cls = modelformset_factory(model=StudentStudyRecord, form=InputSSRecordModelForm, extra=0) queryset = StudentStudyRecord.objects.filter(classstudyrecord=csRecord_id) formset = model_formset_cls(queryset=queryset) # 实例化对象传入筛选结果 return render(request, 'student/stu_score_list.html', {'formset': formset}) # post请求提交数据 def post(self, request, csRecord_id): model_fromset_cls = modelformset_factory(model=StudentStudyRecord, form=InputSSRecordModelForm, extra=0) formset = model_fromset_cls(request.POST) # 实例化对象传入提交信息 if formset.is_valid(): # 校验 formset.save() # 通过校验保存提交信息 return self.get(request, csRecord_id)
4、模板:
<form action="" method="post"> {% csrf_token %} {{ formset.management_form }} # 这里一定要加这句代码 <div class="tpl-block"> <!-- 表格 --> <div class="am-g"> <div class="am-u-sm-12"> <table class="am-table table-main mytable"> <thead> <tr> <th>编号</th> <th>姓名</th> <th>考勤</th> <th>本节成绩</th> <th>作业批语</th> </tr> </thead> <tbody> {% for form in formset %} <tr> # 这里只写了一层for循环,所以手动写字段,必须把id字段写上 {{ form.id }} <td>{{ forloop.counter }}</td> # instance表示该字段只显示,不渲染出来form表单组件,即不可编辑 <td>{{ form.instance.student }}</td> <td>{{ form.instance.get_record_display }}</td> <td>{{ form.score }}</td> <td>{{ form.homework_note }}</td> </tr> {% endfor %} </tbody> </table> <div class="am-u-sm-2 am-u-sm-offset-11"> <button type="submit" class="am-btn">保存</button> </div> </div> </div> </div> </form>
三、统计每个销售的成单量
需求:分别查询每个销售今天,昨天,最近一周,最近一个月的成单量
1、视图函数
import datetime from django.db.models import Count class TongJiView2(View): def today(self): # 今天 today = datetime.datetime.now().date() customer_list = Customer.objects.filter(deal_date=today) # 查询每个销售的名字以及对应的销售今天的成单量 ret = UserInfo.objects.filter(depart_id=2, customers__deal_date=today).annotate(c=Count("customers")).values_list("username", "c") ret = [[item[0], item[1]] for item in list(ret)] return {'customer_list': customer_list, 'ret': ret} def yesterday(self): # 昨天 yesterday = datetime.datetime.now().date() - datetime.timedelta(days=1) customer_list = Customer.objects.filter(deal_date=yesterday) # 查询每个销售的名字以及对应的销售昨天的成单量 ret = UserInfo.objects.filter(depart_id=2, customers__deal_date=yesterday).annotate(c=Count("customers")).values_list("username", "c") ret = [[item[0], item[1]] for item in list(ret)] return {'customer_list': customer_list, 'ret': ret} def week(self): # 最近一周 today = datetime.datetime.now().date() weekago = datetime.datetime.now().date() - datetime.timedelta(weeks=1) customer_list = Customer.objects.filter(deal_date__gte=weekago, deal_date__lte=today) # 查询每个销售的名字以及对应的销售最近一周内的成单量 ret = UserInfo.objects.filter(depart_id=2, customers__deal_date__gte=weekago, customers__deal_date__lte=today).annotate(c=Count("customers")).values_list("username", "c") ret = [[item[0], item[1]] for item in list(ret)] return {"customer_list": customer_list, "ret": ret} def recent_month(self): # 最近一个月 today = datetime.datetime.now().date() monthago = datetime.datetime.now().date() - datetime.timedelta(days=30) customer_list = Customer.objects.filter(deal_date__gte=monthago, deal_date__lte=today) # 查询每个销售的名字以及对应的销售最近一个月内的成单量 ret = UserInfo.objects.filter(depart_id=2, customers__deal_date__gte=monthago, customers__deal_date__lte=today).annotate(c=Count("customers")).values_list("username", "c") ret = [[item[0], item[1]] for item in list(ret)] return {"customer_list": customer_list, "ret": ret} def get(self, request): date = request.GET.get("date", "today") if hasattr(self, date): context = getattr(self, date)() return render(request, 'customer/tongji.html', context)
分析:上面视图类中有很多重复代码,所以可以按下面方式整合
# 成单量统计:整合后 class TongJiView(View): def get(self,request): date = request.GET.get("date", "today") now = datetime.datetime.now().date() delta1 = datetime.timedelta(days=1) delta2 = datetime.timedelta(weeks=1) delta3 = datetime.timedelta(days=30) condition = { "today":[{"deal_date":now},{"customers__deal_date":now}], "yesterday":[ {"deal_date":now - delta1}, {"customers__deal_date":now - delta1}], "week":[ {"deal_date__gte":now-delta2, "deal_date__lte":now}, {"customers__deal_date__gte":now-delta2, "customers__deal_date__lte":now}], "recent_month":[ {"deal_date__gte":now - delta3, "deal_date__lte":now}, {"customers__deal_date__gte":now - delta3, "customers__deal_date__lte":now}], } customer_list = Customer.objects.filter(**(condition.get(date)[0])) ret = UserInfo.objects.all().filter(**(condition.get(date)[1])).annotate(c=Count("customers")).values_list("username","c") ret_x = [item[0] for item in list(ret)] ret_y = [item[1] for item in list(ret)] return render(request,"customer/tongji.html", {'customer_list': customer_list, 'ret_x': ret_x, 'ret_y': ret_y})
四、补充知识点
1、datetime相关
import datetime import pytz # datetime.datetime 年月日时分秒 # datetime.date 年月日 # datetime.time 时分秒 # datetime.timedelta 时间差 now1 = datetime.datetime.now() now = now1.replace(tzinfo=pytz.timezone('UTC')) now2 = datetime.datetime.today() today_date = datetime.datetime.now().date() timenum = datetime.timedelta(days=1) # 一天的时间差 yestoday = datetime.datetime.now().date() - timenum # 今天 - 1 天 = 昨天 week = datetime.timedelta(weeks=1) # 一周时间差 total_seconds = week.total_seconds() # 将上面一周的时间换算成秒数 print(now1) # 2018-11-24 21:53:37.290485 print(now) # 2018-11-24 21:53:37.290485+00:00 print(now2) # 2018-11-24 21:53:37.290486 print(today_date) # 2018-11-24 print(timenum) # 1 day, 0:00:00 print(yestoday) # 2018-11-23 print(week) # 7 days, 0:00:00 print(total_seconds) # 4233600.0
注意:处理时间的时候要注意时区问题。
浙公网安备 33010602011771号