ModelFormset实现的一个实例

主要实现“批量录入”功能

表关系

上课记录表与学生学习记录表:

class ClassStudyRecord(models.Model):
    """
    上课记录表 (班级记录)
    """
    class_obj = models.ForeignKey(verbose_name="班级", to="ClassList",on_delete=models.CASCADE)
    day_num = models.IntegerField(verbose_name="节次", help_text=u"此处填写第几节课或第几天课程...,必须为数字")

    teacher = models.ForeignKey(verbose_name="讲师", to='UserInfo',on_delete=models.CASCADE)
    date = models.DateField(verbose_name="上课日期", auto_now_add=True)
    course_title = models.CharField(verbose_name='本节课程标题', max_length=64, blank=True, null=True)
    course_memo = models.TextField(verbose_name='本节课程内容概要', blank=True, null=True)
    has_homework = models.BooleanField(default=True, verbose_name="本节有作业",)
    homework_title = models.CharField(verbose_name='本节作业标题', max_length=64, blank=True, null=True)
    homework_memo = models.TextField(verbose_name='作业描述', max_length=500, blank=True, null=True)
    exam = models.TextField(verbose_name='踩分点', max_length=300, blank=True, null=True)

    def __str__(self):
        return "{0} day{1}".format(self.class_obj, self.day_num)

class StudentStudyRecord(models.Model):
    '''
    学生学习记录
    '''
    record_choices = (('checked', "已签到"),
                      ('vacate', "请假"),
                      ('late', "迟到"),
                      ('noshow', "缺勤"),
                      ('leave_early', "早退"),
                      )

    record = models.CharField("上课纪录", choices=record_choices, default="checked", max_length=64)
    score_choices = ((100, 'A+'),
                     (90, 'A'),
                     (85, 'B+'),
                     (80, 'B'),
                     (70, 'B-'),
                     (60, 'C+'),
                     (50, 'C'),
                     (40, 'C-'),
                     (0, ' D'),
                     (-1, 'N/A'),
                     (-100, 'COPY'),
                     (-1000, 'FAIL'),
                     )
    score = models.IntegerField("本节成绩", choices=score_choices, default=-1)
    homework_note = models.CharField(verbose_name='作业评语', max_length=255, blank=True, null=True)
    note = models.CharField(verbose_name="备注", max_length=255, blank=True, null=True)
    homework = models.FileField(verbose_name='作业文件', blank=True, null=True, default=None)
    stu_memo = models.TextField(verbose_name='学员备注', blank=True, null=True)
    date = models.DateTimeField(verbose_name='提交作业日期', auto_now_add=True)

    student = models.ForeignKey(verbose_name="学员", to='Student', on_delete=models.CASCADE)
    # 与上课记录表建立外键关联
    classstudyrecord = models.ForeignKey(verbose_name="第几天课程", to="ClassStudyRecord", on_delete=models.CASCADE)


    def __str__(self):
        return "{0}-{1}".format(self.classstudyrecord, self.student)

    class Meta:
        unique_together=["student","classstudyrecord"]

两张表的大致关系如下:

项目大概流程

班级学习记录的模板文件如下

{% extends 'base.html' %}

{% block content %}
  <div class="content-wrapper">
    <!-- Content Header (Page header) -->

    <section class="content-header">
      <h1>
        课程记录
        <small>展示</small>
      </h1>

      <ol class="breadcrumb">
        <li><a href="#"><i class="fa fa-dashboard"></i> Level</a></li>
        <li class="active">Here</li>
      </ol>
    </section>

    <section class="content container-fluid">
      <div class="row">
        <div class="col-xs-12">
          <div class="box">

            <a href="" class="btn btn-primary pull-right">添加记录</a>

            <form action="" method="post">
              {% csrf_token %}
              <select name="action" id="" class="form-control" style="width: 200px;display: inline-block">
                <option value="batch_create">批量创建学生学习记录</option>


              </select>
              <button class="btn btn-danger" style="vertical-align: 1px;">go</button>


              <div class="box-body">
                <table id="example2" class="table table-bordered table-hover">
                  <thead>
                  <tr>
                    <th>
                      <input type="checkbox" id="choose">
                    </th>
                    <th>序号</th>
                    <th>班级</th>
                    <th>节次</th>
                    <th>老师</th>
                    <th>本节课程标题</th>
                    <th>学详</th>
                    <th>操作</th>
                  </tr>
                  </thead>
                  <tbody>
                  {% for record in all_obj %}
                    <tr>
                      <td><input type="checkbox" name="selected_id" value="{{ record.pk }}"></td>
                      <td>{{ forloop.counter }}</td>
                      <td>{{ record.class_obj }}</td>
                      <td>{{ record.day_num }}</td>
                      <td>{{ record.teacher }}</td>
                      <td>{{ record.course_title }}</td>
                      <td><a href="{% url 'study_decord' record.pk %}">学详</a></td>
                      <td>

                        <a href="" class="btn btn-warning btn-xs">编辑</a>
                        <a href="" class="btn btn-danger btn-xs">删除</a>
                      </td>

                    </tr>
                  {% endfor %}

                  </tbody>
                </table>
              </div>
              <!-- /.box-body -->
            </form>
          </div>
          <!-- /.box -->
        </div>
        <!-- /.col -->
      </div>
      <!-- /.row -->
    </section>


  </div>
{% endblock %}

{% block js %}
  <script>
      $('#choose').click(function () {
          var status = $(this).prop('checked');
          $('[name=selected_id]').prop('checked', status);

      })
  </script>

{% endblock %}

点击“学习详情”后的路由如下 

#学详路径
url(r'^study_decord/(\d+)/', views.StudyRecordDeialView.as_view(), name='study_decord'),

具体的视图函数中的处理在下面介绍:

ModelFormset的写法以及视图函数的写法

—— 这里把ModelFormset与视图函数写在一起了

#modelformset
from django.forms.models import modelformset_factory
from django import forms

# 这个是modelformset的写法
class StudyRecordDeialModelForm(forms.ModelForm): class Meta: model = models.StudentStudyRecord # fields = '__all__' fields = ['score','homework_note'] # 这个是批量处理学生成绩的视图函数 class StudyRecordDeialView(View): def get(self, request, class_record_id): class_record_obj = models.ClassStudyRecord.objects.get(pk=class_record_id) all_study_recored = models.StudentStudyRecord.objects.filter( classstudyrecord=class_record_obj, )      # 这个form_set_obj其实是一个类~工厂模式产出的一个modelformset的类 form_set_obj = modelformset_factory(model=models.StudentStudyRecord,form=StudyRecordDeialModelForm,extra=0) formset = form_set_obj(queryset=all_study_recored) return render(request, 'student/study_record_detail.html',{'formset': formset}) def post(self, request, class_record_id): class_record_obj = models.ClassStudyRecord.objects.get(pk=class_record_id) all_study_recored = models.StudentStudyRecord.objects.filter( classstudyrecord=class_record_obj, ) form_set_obj = modelformset_factory(model=models.StudentStudyRecord, form=StudyRecordDeialModelForm, extra=0) formset = form_set_obj(request.POST) if formset.is_valid(): formset.save() else: print(formset.errors) return redirect(reverse('study_decord',args=(class_record_id,)))

学生学习成绩批量操作前端模板渲染

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
</head>
<body>

<h3>录入{{ class_record_obj.class_obj }}day{{ class_record_obj.day_num }}成绩</h3>

<hr>

 <div class="panel panel-default">
        <div class="panel-heading">学习记录</div>
        <div class="panel-body">
            <div style="width: 680px;margin: 0 auto;">
                <form method="post" action="">

                    {% csrf_token %}
<!-- 这句话一定要加上,固定的!!! --> {{ formset.management_form }} <table class="table table-bordered"> <thead> <tr> <th>姓名</th> <th>考勤</th> <th>作业成绩</th> <th>作业评语</th> </tr> </thead> <tbody> {% for form in formset %} <tr> {{ form.id }} <td>{{ form.instance.student }}</td> {# <td>{{ form.instance.student }}</td> #} <td>{{ form.instance.get_record_display }} </td> {# <td>{{ form.instance.get_record_display }} </td> #} <td>{{ form.score }} </td> <td>{{ form.homework_note }}</td> </tr> {% endfor %} </tbody> </table> <input type="submit" value="保存"> </form> </div> </div> </div> <hr> </body> </html>

实现的效果如下

 

posted on 2019-07-17 06:47  江湖乄夜雨  阅读(105)  评论(0编辑  收藏  举报