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 = '学生列表'
来源:oschina
链接:https://my.oschina.net/u/4288213/blog/3603440