day77

day77

先做班级学习记录:

点击批量,关于学生的此次学习记录,到班级里面完成成绩的填写

url 写成多份,url路由分发

. html 
+ 班级学习记录
ulrs.py
url('^class_record ''


views.py
class ClassRecordView(View):
	def get(self,request):
		all_obj = models.CSR.obj.all()
		
admin.py	
study...
.....


customer文件夹


student文件夹

CSR.html

课程记录(存重复)

option	批量创建学生记录
						

classsr.html

td	record.class_obj   对象,有str方法的话显示名字
td	rec.tec				对象

{%ret_html|safe} 分页

做 1

编辑删除增加都没学下课自己写

form 批量增加学习记录

---clRV
	def post(self,re)
		action = request.POST.get('actionv')
		select_id = request.POST.getlist('select_id')	
		
		if hasattr(self,action):
			ret = getattr(self,action)(select_id)
			#return redirect('url别名')
			return self.get(request)	 直接调用get操作减少重定向一遍
	def b_c(self,select_id):
		for cousr_record_id in select_id :  班级课程找属性
			all_stuents  = m.CSR.o.get(pk=c_r_i).class_obj.students.all()	
			for 					all()所有学生
			l1 = []
			for studen in all_s:
				# m.SS.o.cre(stue=stu  ,	csr_id = c_r_i )
			obj = m.SS.o(stue=stu  ,	csr_id = c_r_i )
			l1.ap(obj)
			多对一的写在多地里面,外键
			上课记录-班级-学生-学生记录
			m.S.o.bulk_create(l1)
		
admin.py
class ca..
	list_d = 
	list_e = 
	

amdin做的既可以查看和编辑

公司: 招go的比较多 学go (大型公司)

jingdong ali xinlang toutiao ali: go xuexia

京东 天猫 大型的网站 python搞起来还是比较吃力的

页面上添加

不是点击去编辑,而是直接就可以编辑

class StudyReDetialView(View):
​	def get(self,re,class_recor_id):
		#找到课程记录
		class_r_obj = m.ClaR.o.get(pk = cl_r_i)
		
		# all_st = c_r_o.class_obj.students.all()
​		# 找到这个课程记录所生成的所有学习记录

		mo.SSR.objs.fitler(classstudyrecore	= c_r_i  )
		
		ret render(req,'study_record_detail.html')
		
		
		
	学生表和客户信息表 1对1 关系	get_record_display显示元祖设置的中文
	
	

st/s_r_d.html


--url
#学详
url(r'^s_r//'',v.S.as_view(),)

moderform和form 只能生成一条表单 不能生成多条表单 同时放这一块提交

自己写

考勤:有一个系统,别人填好了

成绩:可以自己写

for choice in c_s:
	option { vlaue= cho.0 selected} cho.1 默认选中
	else : 

html
post ‘’ 当前页面
def post(self,request):
	html网页里加标识 sore_{{pk}}  
	data = re.Post
#	data.pop('csrf')
	for key,val in request.POST.items():
		print(key,val)	 scrf :  ...  score_1 90  homo_note_1 111
		
		字符串分割
			field,pk = key.rsplit('_',1)	
			print(field,pk)
			
		正则_数可以
		
		
		
		

错误 1

The Querydict not immable 不可修改 :深拷贝

if key = 'csrf':
 	continue
field,pk = key.rsplit('_',1)		# score   1 
models.SSR.obj.filter(pk=pk).update()
models.SSR.obj.filter(**{pk:pk}).update()	 默认都是and的关系,所有的这些,因为键值对

models.SSR.obj.filter(**{pk:pk}).update(**{field:val})	
所有的函数都是玩的基础,传参。。。。
return self.get(request,c_re_i)	
return redirect(rever('sty_decor'),args=(clla_re_id))

需要四次循环,二个相同的update两次,效率降低

改数据结构,一次执行

{1:{‘score’ : 88,'HOmewo':'333'},

2:{‘score’ : 88,'HOmewo':'333'}}

data_dict = {}

....
if pk in data_dict :

	#data_dict[pk] = {
	field : val , 
	}
	
	data_dict[pk][field] = val
else:
	data_dict[pk] = {
	field : val , 
}
for spk,data in data_dict.items():
	models.SSR.o.value(**{pk:pk}).f(**{**data})


先查后更新

如果还觉得不好,用原生sql同时执行多条语句的批量

批量创建多条语句

把update给insert 相当于执行多条sql语句 并发去执行了

formset ---form

modelformset ---modelform

view.py

from django.forms.models import modelformset_factory 
from django import forms
class StudyRecordDeial(View):
	class Meta:
		model = m.SSR
		fields = '__all__'
class SRDV(View)		:
	def get(s,r,c):
		f_s_o = modlformset_factory(model= models.SSR,form=SRDM)
		queryset = 
		c_r_o = 	表指定了
		formset = form_set_obj(queryset= all_record)
			修改哪条指令,queryset指定
		
		

form extra = 1 额外多一个

默认把所有的字段都加了下拉框

insatance 拿原来的值摆在这里student

显示:
record ,  late
get_record_display 迟到

name = 'form-1-id'	 背后也是默认干切分。。。


def post(s,r,c):
	forset = form_set_obj(req.POST)		#
	if formset.is_valid()
		formset.save()
	else:
		print(formset.errors)	都是必填的 
		modelform做的验证,fields = '__all__'	是所有的
		fields = ['sorce','homework_note']	
		

区分不同的app下的,用命名空间

不会有冲突

{% url 'app01:detail' pk=12 pp=99 %}

  views中的函数中使用 将app01写好

v = reverse('app01:detail', kwargs={'pk':11})

不写app_name = 'app01' 写了也得写 app01:detail

django 进阶

model进阶

QuerySet (类列表)
惰性查询
特点: 
可切片
可迭代
惰性查询(modelset不会查询,什么时候用才会查询)



af_pr

models.py 表

csr : 上什么课 
ssr: 学生学习记录

如何通过班级记录批量创建学生学习记录,生成一个表格形式的里面可以改内容

客户信息部分: 看总的(管理员),看有些部分的,有区分

文件夹
--templates
	--customer
		customer/add/
	--student

生成models.py + 在admin里写添加页面(register) + admin加数据

展示班级记录,批量操作,

<td>{{ record.class_obj }}</td> #直接找到班级的对象 ——str的return值


之前显示编辑

之前的显示编辑: 得望后台去提交,而且只能提交一次(基于原生的form和modormform) 基于base页面写的页面,

<td><input type="checkbox" name="selected_id" value="{{ record.pk }}"></td>

在for循环里
request.POST.getlist(select_id 就是record_id 。。。。


    <select name="action" id="" class="form-control" style="width: 200px;display: inline-block">
    <option value="batch_create">批量创建学生学习记录</option>
    
request.POST.get(action 就是 batch_create      

写函数的时候

   return self.get(request) 直接掉用get方法  post了浏览器又走get方法
	#减少一次中间项

models.py
default check都是默认选中的

错误1

插入了,认真

UNIQUE constraint failed: nbapp_studentstudyrecord.student_id, nbapp_studentstudyrecord.classstudyrecord_id

错误原因: 违反唯一性约束 你对表做create和update的时候对该字段的插入值重复了

错误2

把学生自定义的类给了班级

admin.site.register(models.ClassStudyRecord,StudentStudyRecordView)

对象有str方法是customer 一对一

<td>{{ studentstudyrecord.student }}</td>

(1)textarea cols 高

form action里面为空,默认当前页,提交走post

错误3

下面的两个哪个不一样,为什么一个study_record 无法匹配的到?

正常匹配得到的话,"{url 'study_record' record.pk}" 是可以点过去的

    url(r'^study_record/(\d+)/', views.StudyRecordDetialView.as_view(), name='study_record '),

    # url(r'^study_record/(\d+)/', views.StudyRecordDetialView.as_view(), name='study_record'),


name 第一个的多加了一个空格。。。。

print(request.POST)
# home_note = ['ddd','ddd']这样 sorce = [38,89]这样 
为了方便区分那里加上了 sore_{{pk}}  home_note_{{pk}}  有了区分

def get(self,request,class_record_id):
def post(self,request,class_record_id):   路径有delete/1/所以有ID


前端提交的东西 是有name=''的

        for field,val in request.POST.items() :     #<QueryDict: {'csrfmiddlewaretoken': ['rMxfWl8eoGMuodgpzrYxBVH0qg2TsR4Ou1tDpEWBSOqOODpZ7xMV8lNQju9P39dY'], 'score_choice_1': ['90'], 'homework_note_1': ['sdafd'], 'score_choice_2': ['85'], 'homework_note_2': ['adafs']}>
            print(field,val)        
            '''csrfmiddlewaretoken 2BoIUok0U6IOSwj2hKoSfVR0P2Se2k1J5Qk6nH8noem8iWsCPQcgMlXQIgZaDCaT
                score_choice_1 85
                homework_note_1 sdafd
                score_choice_2 100
                homework_note_2 asdfsaf'''


(2)data_dict = {}的位置影响
 
        data_dict = {}
        for key,val in request.POST.items() :    
            if key == 'csrfmiddlewaretoken':
                continue
            field , pk = key.rsplit('_',1) 
            if pk in data_dict :
                data_dict[pk][field] = val
            else :
                data_dict[pk] = {
                    field :val,
                }
            print('>>>>',data_dict)
        for spk , sdata in data_dict.items():
            models.StudentStudyRecord.objects.filter(**{'pk': spk}).update(**sdata)

结果显示

>>>> {'1': {'score': '100', 'homework_note': '真是个好孩子大阿斯顿发生按地方撒法师阿斯顿发'}, '2': {'score': '90', 'homework_note': 'asdad按地方撒'}}

 
        for key,val in request.POST.items() :    
            if key == 'csrfmiddlewaretoken':
                continue
            field , pk = key.rsplit('_',1) 
            
        	data_dict = {}
            if pk in data_dict :
                data_dict[pk][field] = val
            else :
                data_dict[pk] = {
                    field :val,
                }
            print('>>>>',data_dict)
        for spk , sdata in data_dict.items():
            models.StudentStudyRecord.objects.filter(**{'pk': spk}).update(**sdata)

结果显示

>>>> {'1': {'score': '100'}}
>>>> {'1': {'homework_note': '真是个好孩子大按地方撒法师阿斯顿发'}}
>>>> {'2': {'homework_note': 'asdad按地方撒'}}

(3)第一种效率低的做法,效率低吗,不大好看是真吧
     def post(self,request,class_record_id):
        print(request.POST) # home_note = ['ddd','ddd']这样  sorce = [38,89]这样  为了方便区分那里加上了
        class_record_obj = models.ClassStudyRecord.objects.get(pk=class_record_id)  #课程记录
        # class_record_obj.class_obj.students.all()   #所有的学生
        all_study_records = models.StudentStudyRecord.objects.filter(   # 找到这个课程记录的所有学生记录
            #关联了课程记录  class——record-id
            classstudyrecord=class_record_obj,
        )
        score_choices = models.StudentStudyRecord.score_choices     #类的属性
        for key,val in request.POST.items() :     #<QueryDict: {'csrfmiddlewaretoken': ['rMxfWl8eoGMuodgpzrYxBVH0qg2TsR4Ou1tDpEWBSOqOODpZ7xMV8lNQju9P39dY'], 'score_choice_1': ['90'], 'homework_note_1': ['sdafd'], 'score_choice_2': ['85'], 'homework_note_2': ['adafs']}>
            print(key,val)
            '''csrfmiddlewaretoken 2BoIUok0U6IOSwj2hKoSfVR0P2Se2k1J5Qk6nH8noem8iWsCPQcgMlXQIgZaDCaT
                score_choice_1 85
                homework_note_1 sdafd
                score_choice_2 100
                homework_note_2 asdfsaf'''
            if key == 'csrfmiddlewaretoken':
                continue
            field , pk = key.rsplit('_',1) #    score_choice_1 85  -->  score_choice    85
            print(field,pk)
            # models.StudentStudyRecord.objects.filter(pk=pk).update()

            models.StudentStudyRecord.objects.filter(**{'pk': pk}).update(**{field:val})
                    # 打散传参和上面的情况一样,只不过是和的关系  但是注意这里是 ** 'pk' 不是**{pk:pk}
        # return render(request,'student/study_record_detail.html',{'class_record_obj':class_record_obj,
        #                                                           'score_choices':score_choices,'all_study_records': all_study_records })
        # return self.get(request,class_record_id)
        return redirect( reverse('study_record',args=(class_record_id,)))


formset
models.py

default 是已签到,= checked 默认值


def get()

	formset  有个参数 点进去   有个extra=1多一行了

html

   {{ formset.management_form }}        {# 类似于csrf认识的标识符      #}
                <table class="table table-bordered">
                    <thread>
                        <tr>
                            <th>姓名</th>
                            <th>考勤</th>
                            <th>作业成绩</th>
                            <th>作业评语</th>
                        </tr>
                    </thread>
                    <tbody>
                        {% for form in formset %}   {# formset 就包括了一条条记录#}
                            <tr>
                                {{ form.id }}       {# pk值#}
                                <td>{{ form.student }}</td>  {#默认会自动生成下拉框 ,如果不让他渲染,#}
                                                        {#那么需要使用form.instance.student.这是form对象原值,原来的数据#}

                            <td>{{ form.get_record_display }}</td>
{#                            <td>{{ form.instance.get_record_display }}</td>#}
                            <td>{{ form.score }}</td>
                            <td>{{ form.homework_note }}</td>
                            </tr>

                        {% endfor %}

extra =1 错误3

加了的值

extra=1这个不用给他赋值了,要付也得把id给了

给这个N/A 后边的评语加值了  。。。

NOT NULL constraint failed: nbapp_studentstudyrecord.classstudyrecord_id

非空约束失败:nbapp_studentstudyrecord.classstudyrecord_id

错误4

get和post的不一样

def get():
form_set_obj(query= all_study_record)
def post():
form_set_obj(request.POST)

formset 使用
from django.forms.models import modelformset_factory
from django import forms
class StudyRecordDetialModelForm(forms.ModelForm):
    class Meta:
        model = models.StudentStudyRecord
        # fields = '__all__'
        fields = ['score','homework_note']
class StudyRecordDetialView2(View):
      def get(self,request,class_record_id):
          all_study_record = models.StudentStudyRecord.objects.filter(  # 找到这个课程记录的所有学生记录
                          classstudyrecord=class_record_id,
                      )
          form_set_obj = modelformset_factory(model=models.StudentStudyRecord,form=StudyRecordDetialModelForm)
                    # 哪张表(model)来使用modelformset  使用这张表来加工表的时候用的哪个modermform(from)
          formset = form_set_obj(queryset = all_study_record)   #使用all_study_record来加工query记录
                    # 来加工modermform的哪些数据,通过queryset来指定
          return render(request, 'student/study_record_detail.html', { 'formset': formset })


      def post(self,request,class_record_id):
          all_study_record = models.StudentStudyRecord.objects.filter(  # 找到这个课程记录的所有学生记录
              classstudyrecord=class_record_id,
          )
          form_set_obj = modelformset_factory(model=models.StudentStudyRecord, form=StudyRecordDetialModelForm,extra=0)
          # 哪张表(model)来使用modelformset  使用这张表来加工表的时候用的哪个modermform(from)
          formset = form_set_obj(request.POST)  # 使用all_study_record来加工query记录
          # 来加工modermform的哪些数据,通过queryset来指定
          if formset.is_valid():
              formset.save()
          else:
              print(formset.errors)
          #
          # return redirect(reverse('study_record',args=(class_record_id,)))
          return self.get(request,class_record_id)
          # return request.get(request,class_record_id)

在课程页面批量创建多个学生记录
class ClassRecordView(View):
    def get(self,request):
        all_obj = models.ClassStudyRecord.objects.all()
        return render(request,'student/class_study_record.html',{'all_obj':all_obj})

    def post(self,request):
        action = request.POST.get('action')
        selected_id = request.POST.getlist('selected_id')
        if hasattr(self,action):
            ret = getattr(self,action)(selected_id)      #()对应创建的id
            # return redirect()
        return self.get(request)


    def batch_create(self,selected_id):
        #班级记录 管理班级 找student找不到  找s再找ssr

        for course_record_id in selected_id:
            all_students = models.ClassStudyRecord.objects.get(pk=course_record_id).class_obj.students.all()    #record_id 是all_obj的CSR的id
                                                    #不写的话写student.set__all()                     #关联的students relate_name 代替类名小写

#多对一的关系,外键是写在了多的表里,多的表找属性
            l1 = []
            for student in all_students:    # 小黑  梨花

                # models.StudentStudyRecord.objects.create(student=student,classstudyrecord_id=course_record_id)
                # 2 批量创建
                obj = models.StudentStudyRecord(student=student,classstudyrecord_id=course_record_id)
                l1.append(obj)
            models.StudentStudyRecord.objects.bulk_create(l1)


批量创建学生页面

class课程班级

在一个页面展示修改提交到后台保存

版本一 post 多次提交
class StudyRecordDetialView(View):
    def get(self,request,class_record_id):
        class_record_obj = models.ClassStudyRecord.objects.get(pk=class_record_id)  #课程记录

        # class_record_obj.class_obj.students.all()   #所有的学生
        all_study_records = models.StudentStudyRecord.objects.filter(   # 找到这个课程记录的所有学生记录
            #关联了课程记录  class——record-id
            classstudyrecord=class_record_obj,
        )
        score_choices = models.StudentStudyRecord.score_choices     #类的属性

        return render(request,'student/study_record_detail.html',{'class_record_obj':class_record_obj,
                                                                  'score_choices':score_choices,'all_study_records': all_study_records })

    def post(self,request,class_record_id):
        print(request.POST) # home_note = ['ddd','ddd']这样  sorce = [38,89]这样  为了方便区分那里加上了
        class_record_obj = models.ClassStudyRecord.objects.get(pk=class_record_id)  #课程记录
        # class_record_obj.class_obj.students.all()   #所有的学生
        all_study_records = models.StudentStudyRecord.objects.filter(   # 找到这个课程记录的所有学生记录
            #关联了课程记录  class——record-id
            classstudyrecord=class_record_obj,
        )
        score_choices = models.StudentStudyRecord.score_choices     #类的属性
        for key,val in request.POST.items() :     #<QueryDict: {'csrfmiddlewaretoken': ['rMxfWl8eoGMuodgpzrYxBVH0qg2TsR4Ou1tDpEWBSOqOODpZ7xMV8lNQju9P39dY'], 'score_choice_1': ['90'], 'homework_note_1': ['sdafd'], 'score_choice_2': ['85'], 'homework_note_2': ['adafs']}>
            print(key,val)
            '''csrfmiddlewaretoken 2BoIUok0U6IOSwj2hKoSfVR0P2Se2k1J5Qk6nH8noem8iWsCPQcgMlXQIgZaDCaT
                score_choice_1 85
                homework_note_1 sdafd
                score_choice_2 100
                homework_note_2 asdfsaf'''
            if key == 'csrfmiddlewaretoken':
                continue
            field , pk = key.rsplit('_',1) #    score_choice_1 85  -->  score_choice    85
            print(field,pk)
            # models.StudentStudyRecord.objects.filter(pk=pk).update()

            models.StudentStudyRecord.objects.filter(**{'pk': pk}).update(**{field:val})
                    # 打散传参和上面的情况一样,只不过是和的关系  但是注意这里是 ** 'pk' 不是**{pk:pk}
        # return render(request,'student/study_record_detail.html',{'class_record_obj':class_record_obj,
        #                                                           'score_choices':score_choices,'all_study_records': all_study_records })
        # return self.get(request,class_record_id)
        return redirect( reverse('study_record',args=(class_record_id,)))

版本二 提升效率 设计数据结构
  # 为了节省 两个更新
    def post(self,request,class_record_id):
        print(request.POST) # home_note = ['ddd','ddd']这样  sorce = [38,89]这样  为了方便区分那里加上了
        class_record_obj = models.ClassStudyRecord.objects.get(pk=class_record_id)  #课程记录
        # class_record_obj.class_obj.students.all()   #所有的学生
        all_study_records = models.StudentStudyRecord.objects.filter(   # 找到这个课程记录的所有学生记录
            #关联了课程记录  class——record-id
            classstudyrecord=class_record_obj,
        )
        '''
            {
            1 : {'score':85,'homework_not':'33',
            2 : {'score':85,'homework_not':'33',
            }
        '''
        score_choices = models.StudentStudyRecord.score_choices     #类的属性
        data_dict = {}
        for key,val in request.POST.items() :     #<QueryDict: {'csrfmiddlewaretoken': ['rMxfWl8eoGMuodgpzrYxBVH0qg2TsR4Ou1tDpEWBSOqOODpZ7xMV8lNQju9P39dY'], 'score_choice_1': ['90'], 'homework_note_1': ['sdafd'], 'score_choice_2': ['85'], 'homework_note_2': ['adafs']}>
            print(key,val)
            if key == 'csrfmiddlewaretoken':
                continue
            field , pk = key.rsplit('_',1) #    score_choice_1 85  -->  score_choice    85
            if pk in data_dict :
                data_dict[pk][field] = val
            else :
                data_dict[pk] = {
                    field :val,
                }
            print('>>>>',data_dict)
        for spk , sdata in data_dict.items():
            models.StudentStudyRecord.objects.filter(**{'pk': spk}).update(**sdata)
                    # 打散传参和上面的情况一样,只不过是和的关系  但是注意这里是 ** 'pk' 不是**{pk:pk}
        # return render(request,'student/study_record_detail.html',{'class_record_obj':class_record_obj,
        #                                                           'score_choices':score_choices,'all_study_records': all_study_records })
        # return self.get(request,class_record_id)
        return redirect( reverse('study_record',args=(class_record_id,)))


class_study_record.html
        <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>


                    <!-- /.box-header -->
                        <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>
{#                                <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_record' record.pk %}">学详</a></td>#}
                                            <td><a href="{% url 'study_record' record.pk %}">学详</a></td>

                                          <td>
                                            <a href="" class="btn btn-warning btn-xs">编辑</a>
                                            <a href="" class="btn btn-danger btn-xs">删除</a>
                                        </td>
{#                                        <td>{{ customer.get_classlist }}</td>#}
                                    </tr>
                                {% endfor %}

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

自定义编辑admin那样的编辑页面

formset提交的页面

posted @ 2019-06-20 12:25  learnacode  阅读(253)  评论(0编辑  收藏  举报