Top

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

   注意:处理时间的时候要注意时区问题。

posted @ 2018-11-20 19:10  勇敢的巨蟹座  阅读(348)  评论(0)    收藏  举报