ModelFormset

一:ModelFormset

1.1:models.py

class Student(models.Model):
    """
    学生表(已报名)
    """
    customer = models.OneToOneField(verbose_name='客户信息', to='Customer',on_delete=models.CASCADE,null=True,blank=True)
    class_list = models.ManyToManyField(verbose_name="已报班级", to='ClassList', blank=True,related_name="students")

    emergency_contract = models.CharField(max_length=32, blank=True, null=True, verbose_name='紧急联系人')
    company = models.CharField(verbose_name='公司', max_length=128, blank=True, null=True)
    location = models.CharField(max_length=64, verbose_name='所在区域', blank=True, null=True)
    position = models.CharField(verbose_name='岗位', max_length=64, blank=True, null=True)
    salary = models.IntegerField(verbose_name='薪资', blank=True, null=True)
    welfare = models.CharField(verbose_name='福利', max_length=256, blank=True, null=True)
    date = models.DateField(verbose_name='入职时间', help_text='格式yyyy-mm-dd', blank=True, null=True)
    memo = models.CharField(verbose_name='备注', max_length=256, blank=True, null=True)

    def __str__(self):
        return self.customer.name

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):
    '''
    学生学习记录
    '''
    student = models.ForeignKey(verbose_name="学员", to='Student',on_delete=models.CASCADE)
    classstudyrecord = models.ForeignKey(verbose_name="第几天课程", to="ClassStudyRecord",on_delete=models.CASCADE)
    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)

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

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


1.2:url.py

from django.conf.urls import url
from django.contrib import admin

from nbapp import views
urlpatterns = [
    # 班级学习记录
    url(r'^class_record/', views.ClassRecordView.as_view(), name='class_record'),
    
    # 学详路径
    url(r'^study_decord/(\d+)/', views.StudyRecordDeialView.as_view(), name='study_decord'),

]
    


1.3:views.py

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


# 创建一个forms
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)
        # 找到课程记录的obj

        # 找到这个课程记录 所生成的所有学生学习记录
        all_study_recored = models.StudentStudyRecord.objects.filter(
            classstudyrecord=class_record_obj,
        )

        form_set_obj = modelformset_factory(model=models.StudentStudyRecord, form=StudyRecordDeialModelForm, extra=0)
        # 把这个表给modelformset_factory   针对这行表 进行了modelform的加工  得到了一个对象 form_set_obj
        # 最后会多一行,可以用extra=0指定不要多加的这一行

        formset = form_set_obj(queryset=all_study_recored)
        # 针对StudentStudyRecord表 ,使用StudyRecordDeialModelForm 来加工所有这张表里的all_study_recored记录
        # 加工表里的哪些数据 , 通过queryset 指定

        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)
        # 最后会多一行,可以用extra=0指定不要多加的这一行
        formset = form_set_obj(request.POST)

        if formset.is_valid():
            formset.save()
        else:
            print(formset.errors)
        # 因为 效验的是所有的字段 ,所以应该在forms里指定字段

        return redirect(reverse('study_decord', args=(class_record_id,)))


1.4:study_record_detail.html

{% 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="text-center">录入{{ class_record_obj.class_obj }}day{{ class_record_obj.day_num }}成绩</h3>
{# 录入Linux中高级10(北京校区)day51成绩 #}
<br>

<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 }}  <!-- 这句话一定要加上,固定的。是一个modelformset标识符 -->

                <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.student }}</td> #}
{# 默认会自动做成下拉框,如果不让他渲染,那么需要使用 form.instance.student,这是form对象的原值,原来的数据 #}
                            <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>




猜你喜欢

转载自www.cnblogs.com/Quantum-World/p/11061599.html