Django - CRM项目(4)- 批量创建学生记录、基于modelformset录入成绩、统计成单量
一、crm项目
需求:
1、批量创建学生学习记录
2、基于modelformset组件实现录入学生成绩
3、实现统计各个销售的成单量(借助highcharts或echarts显示)
二、modelformset组件
常用于批量处理多个form表单。使用示例如下:
1、引入modelformset的工厂函数
|
1
|
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、视图函数
# 成单量统计:整合后 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})
分析:上面视图类中有很多重复代码,所以可以按下面方式整合
# 成单量统计:整合后
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号