知识点1
前面我们实现了这个功能,就是在models中如果有了choice选项,我们可以实现在页面显示这个chocice的value值,而不是key值,我们这个知识点就是在优化一下这个点
首先如果表中有多个有choice的字段,我们难道要为每个字段都写一个函数吗,当然这个是现实的,但是确认是繁琐的
比如我们要展示2个有choice的字段,我们就需要为每个字段写2个函数
def list_record(self,obj=None,header=False): if header: return "签到情况" else: print(obj.record) print(obj.get_record_display()) return obj.get_record_display() def list_score(self,obj=None,header=False): if header: return "成绩" else: print(obj.score) print(obj.get_score_display()) return obj.get_score_display()
我们可以在showlist中为这个字段做单独的处理,请看下面的代码
if field_obj.choices: print(field_obj.choices,"field_obj.choices",sep="<++++++++++++++++++++++++>") temp = getattr(obj,"get_" + i + "_display") else: temp = getattr(obj,i)
我们打印的字段的choice的值如下
所以我们这里可以利用反射,实现get_字段_display的方法,重点是这里
这样,我们在list_display中就可以直接写字段了
list_display = ["student","score","record","course_record"]
知识点2
复习一下添加一个批量操作的函数的方法,具体的代码如下
class CourseRecordconfig(Starkclass): def test_action(self, request,queryset): print(queryset,"测试生成学习记录2") for cr in queryset: class_course = cr.class_obj.course class_semester = cr.class_obj.semester temp = models.Student.objects.filter(class_list=cr.class_obj) for student in temp: models.StudyRecord.objects.create( student = student, course_record = cr ) print(student,"测试生成学习记录3") actions = [test_action,] # test_action.__name__ = "测试批量操作的函数" test_action.short_description = "测试生成学习记录"
知识点3
之前我们实现了list_filter的功能,现在我们需要实现另外一个功能,就是我们在课程记录表中需要添加一个a标签的一列,点击这个a标签就会能跳转到这个课程中的所有的学生的学习记录中
首先我们需要先实现把a标签显示到页面上,代码如下
def to_study_record(self,obj=None,header=False): if header: return "学生记录" else: href_url = "<a href='/stark/crm/studyrecord/?course_record={num}'>跳转</a>".format(num = obj.id) return mark_safe(href_url) list_display = ["class_obj","day_num","teacher",to_study_record]
页面的效果如下
下面我们要实现过滤,因为我们不能把所有的学生显示出来,只能显示属于这个班级的学生,由于我们在url中已经把当前班级的id已经传进去了,下面就看下我们的过滤的函数该如何处理了
def get_filter(self,request): from django.db.models import Q q_filter_obj = Q() q_filter_obj.connector = "and" if self.list_filter: for k in self.list_filter: if request.GET.get(k,None): temp = (k,request.GET.get(k)) q_filter_obj.children.append(temp) else: print(request.GET,"hahahahaha",type(request.GET)) if request.GET: for k,v in request.GET.items(): if k == "p": pass else: temp = (k,request.GET.get(k)) q_filter_obj.children.append(temp) return q_filter_obj
首先我们在没有定义list_filter,但是我们还要实现过滤,所以我们这里我们要新加了一个逻辑
同样,过滤的字段需要把分页的参数去掉
这样,我们点击按钮,就会显示出这个班级的所有学生的记录
知识点4
在学习记录表中实现一个功能,就是批量编辑学生的签到情况,批量设置签到情况为迟到
代码如下
def pathc_later(self,request,queryset): queryset.update( record = "late" ) pathc_later.short_description = "批量迟到操作" actions = [pathc_later,]
这里稍微看models中的字段
class StudyRecord(models.Model): course_record = models.ForeignKey(verbose_name="第几天课程", to="CourseRecord") student = models.ForeignKey(verbose_name="学员", to='Student') record_choices = (('checked', "已签到"), ('vacate', "请假"), ('late', "迟到"), ('noshow', "缺勤"), ('leave_early', "早退"), ) record = models.CharField("上课纪录", choices=record_choices, default="checked", max_length=64)
页面效果如下,该功能已经实现
知识点5
实现一个如下的功能,在课程记录表中新增一列,点击这一列会跳转到这个班级的这一节次的学生的签到和学习成绩的信息
看到上面的需求,我们又需要自己在新增一个url,首先我们需要先新增一个一列,而这 一列的值都是a标签,a标签的href指向一个新的url
def to_study_record(self,obj=None,header=False): if header: return "学生记录" else: href_url = "<a href='/stark/crm/studyrecord/?course_record={num}'>跳转</a>".format(num = obj.id) return mark_safe(href_url)
这url中我们传递一个这节次课程的id就可以了
上面的url跳转到学习记录表中,这里我们直接复用了学习记录表,没有单独写url对应的视图函数,所以这里我们只需要在学习记录表中过滤课程编辑即可
所以需要修改一下获取过滤条件的函数,为我们这个做单独的处理
def get_filter(self,request): from django.db.models import Q q_filter_obj = Q() q_filter_obj.connector = "and" if self.list_filter: for k in self.list_filter: if request.GET.get(k,None): temp = (k,request.GET.get(k)) q_filter_obj.children.append(temp) else: if request.GET: for k,v in request.GET.items(): if k == "p": pass else: temp = (k,request.GET.get(k)) q_filter_obj.children.append(temp) return q_filter_obj
我们的代码会单独走一条逻辑,实现的作用就是没有配置list_filter也能实现过滤,这里是一个小技巧
知识点6
实现一个可以批量录入这个班级这一节课成绩的需求
首先我们需要先新增一列数据
def record_score(self,obj=None,header=False): if header: return "录入成绩" else: record_score_url = "<a href='/stark/crm/courserecord/record_score/course_record={num}'>录入成绩</a>".format(num = obj.id) return mark_safe(record_score_url)
然后新增一个url
def extra_url(self): temp = [] temp_url = url(r'record_score/course_record=(?P<courseid>\d+)',self.record_socre_func) temp.append(temp_url) return temp
然后写一个url对应的视图函数,分别对post和get的两种方式做单独的处理,这里主要是处理数据和之前不一样,因为这里是批量处理的,可以仔细研究一下代码
def record_socre_func(self,request,courseid): if request.method == "GET": obj_list = models.StudyRecord.objects.filter(course_record__id=courseid) return render(request,"record_score.html",locals()) else: import re re_comp = re.compile(".*\d+$") print(dir(request.POST)) new_update_dict = {} for k,v in request.POST.items(): if k == "csrfmiddlewaretoken": continue else: if re.match(re_comp, k): field,pk = k.rsplit("_",1) if pk in new_update_dict.keys(): new_update_dict[pk][field] = v else: new_update_dict[pk] = {field: v} for k,v in new_update_dict.items(): models.StudyRecord.objects.filter(id=int(k)).update( **v ) # for k,v in request.POST.items(): # if v: # # if re.match(re_comp,k): # field,pk = k.rsplit("_",1) # # obj = models.StudyRecord._meta.get_field(field) # # models.StudyRecord.objects.filter(id=int(pk)).update( # # obj = v # # ) # # if field == "record": # models.StudyRecord.objects.filter(id=int(pk)).update( # record = v # ) # elif field == "score": # models.StudyRecord.objects.filter(id=int(pk)).update( # score = int(v) # ) # else: # models.StudyRecord.objects.filter(id=int(pk)).update( # homework_note = v # ) return redirect(request.path)
这里我们还需要写一个单独的页面,页面的代码主要要注意我们的form表单里的k值是如何设定的
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/css/bootstrap.min.css"> </head> <body> <h3>录入成绩</h3> <div class="container"> <div class="row"> <div class="col-md-9"> <form method="post"> {% csrf_token %} <table class="table table-bordered table-striped"> <thead> <tr> <th>姓名</th> <th>考清</th> <th>成绩</th> <th>批语</th> </tr> </thead> <tbody> {% for stu in obj_list %} <tr> <td>{{ stu.student }}</td> <td> <select class="form-control" name="record_{{ stu.id }}"> {% for record in stu.record_choices %} {% if stu.get_record_displ == record.1 %} <option value="{{ record.0 }}" selected="selected">{{ record.1 }}</option> {% else %} <option value="{{ record.0 }}" selected="selected">{{ record.1 }}</option> {% endif %} {% endfor %} </select> </td> <td> <select class="form-control" name="score_{{ stu.id }}"> {% for score in stu.score_choices %} {% if stu.get_score_display == score.1 %} <option value="{{ score.0 }}" selected="selected">{{ score.1 }}</option> {% else %} <option value="{{ score.0 }}">{{ score.1 }}</option> {% endif %} {% endfor %} </select> </td> <td><textarea cols="30" rows="4" name="homework_note_{{ stu.id }}" class="form-control"> {{ stu.homework_note }} </textarea></td> </tr> {% endfor %} </tbody> </table> <input type="submit" class="btn btn-success pull-right" value="确认提交"> </form> </div> </div> </div> </body> </html>
这个页面的效果如下