django类视图介绍与类视图装饰器
django框架是MTV框架
views.py中def定义的视图是基于函数的视图,class定义的视图是基于类的视图。 --- 分为普通类视图,通用类视图
- 特定的Http方法,get post单独的方法。
- 继承,多重继承 代码分解成可以复用的组件。
1.类视图介绍
普通类视图,目的在于:特定的Http方法,get post单独的方法。
重写views.py中的index。改写成类IndexView。
from django.views import View #导入类视图
class IndexView(View): def get(self,request): num = request.COOKIES.get('num',None) if num: num = str(int(num)+1) else: num = 1 response=render(request,'teacher/index.html',context={ 'num':num }) response.set_cookie('num',num,max_age=20) #max_age保存多少秒,整数,expiry设置过期时间 return response def post(self,request): 还可以重写post等。 pass
urls.py路由中做如下修改:
path('index/', views.IndexView.as_view(),name='index'),
实例二,使用普通类视图,重写编辑学生详情的new_edit方法
class EditStudentView(View): student_form_class = StudentForm #绑定Form表单绑定 student_detail_form_class = StudentDetailForm template_name = 'teacher/student_edit_form.html' section = '学生信息修改' def get(self,request,pk): student = Student.objects.get(pk=pk) # grades = Grade.objects.all() form = self.student_form_class(instance=student) try: detail_form = self.student_detail_form_class(instance=student.studentdetail) except: # 说明学生对象还没有学生详情 student_detail = StudentDetail() student_detail.student = student student_detail.save() detail_form = self.student_detail_form_class(instance=student_detail) return render(request,'teacher/student_edit_form.html',context={ 'section':self.section, 'student':student, 'form':form, 'detail_form':detail_form }) def post(self,request,pk): student = Student.objects.get(pk=pk) form = self.student_form_class(request.POST, instance=student) detail_form = self.student_detail_form_class(request.POST, instance=student.studentdetail) if form.is_valid() and detail_form.is_valid(): form.save() detail_form.save() return redirect(reverse('teacher:students')) return render(request, 'teacher/student_edit_form.html', context={ 'section': self.section, 'student': student, 'form': form, 'detail_form': detail_form })
修改路由urls.py
path('newedit/<int:pk>/',views.EditStudentView.as_view(),name='new_edit'),
通用类视图:ListView
重写students view视图
from django.views.generic import ListView #通用视图 class StudentListView(ListView): template_name = 'teacher/students.html' model = Student context_object_name = 'students' paginate_by = 3 section = '学生列表' def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['section']=self.section context['search'] = self.request.GET.get('search','').strip() context['per_page'] = self.paginate_by context['page'] = int(self.request.GET.get('page',1)) context['students'] = context['page_obj'] return context def get_queryset(self):#改变渲染到模板前面的对象列表 # 获取查询参数 search = self.request.GET.get('search', '').strip() # 每页显示多少数据 per_page = self.request.GET.get('per_page', 10) self.paginate_by = int(per_page) if search: if search.isdigit(): sts = self.model.objects.filter(Q(qq=search) | Q(phone=search), is_deleted=False).order_by('-e_time') # 是qq或者电话 else: sts = self.model.objects.filter(name__contains=search, is_deleted=False).order_by('-e_time') else: sts = self.model.objects.filter(is_deleted=False).order_by('-e_time') return sts
urls.py修改
path('newstudents/',views.StudentListView.as_view(),name='newstudents'),
通用类视图:DetailView
重写学生详情
views.py中添加
from django.views.generic import ListView,DetailView
class StudentDetailView(DetailView): template_name = 'teacher/student_detail.html' model = Student
urls.py中添加
path('studentdetail/<int:pk>/',views.StudentDetailView.as_view())
渲染页面student_detail.html
<body> {{ object }} </body> </html>
3. 类视图装饰器(2种方法)
在urls中装饰 ,必须登录才能查看 (适用于在主目录下对所有路径添加,所有都需要验证的情况)
from django.contrib.auth.decorators import login_required path('newstudents/',login_required(views.StudentListView.as_view()),name='newstudents'),
第二种方法:
装饰类
1.如果没有显示指定get,post方法,直接装饰分发的装饰器
from django.utils.decorators import method_decorator #方法装饰器 class StudentListView(ListView): template_name = 'teacher/students.html' model = Student # context_object_name = 'students' paginate_by = 3 section = '学生列表' @method_decorator(login_required) def dispatch(self, request, *args, **kwargs): return super().dispatch(request,*args, **kwargs) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['section']=self.section context['search'] = self.request.GET.get('search','').strip() context['per_page'] = self.paginate_by context['page'] = int(self.request.GET.get('page',1)) context['students'] = context['page_obj'] return context def get_queryset(self):#改变渲染到模板前面的对象列表 # 获取查询参数 search = self.request.GET.get('search', '').strip() # 每页显示多少数据 per_page = self.request.GET.get('per_page', 10) self.paginate_by = int(per_page) if search: if search.isdigit(): sts = self.model.objects.filter(Q(qq=search) | Q(phone=search), is_deleted=False).order_by('-e_time') # 是qq或者电话 else: sts = self.model.objects.filter(name__contains=search, is_deleted=False).order_by('-e_time') else: sts = self.model.objects.filter(is_deleted=False).order_by('-e_time') return sts
2.或者直接装饰,get,post
class IndexView(View): @method_decorator(login_required) def get(self,request): num = request.COOKIES.get('num',None) if num: num = str(int(num)+1) else: num = 1 response=render(request,'teacher/index.html',context={ 'num':num }) response.set_cookie('num',num,max_age=20) #max_age保存多少秒,整数,expiry设置过期时间 return response
3.装饰类 ,两个参数,第一个是使用的login验证方法,第二个是dispatch。分发
@method_decorator(login_required,name='dispatch') class StudentListView(ListView): template_name = 'teacher/students.html' model = Student # context_object_name = 'students' paginate_by = 3 section = '学生列表'