django.views.decorators.http import require_http_methods
:这个装饰器需要传递一个允许访问的方法的列表。比如只能通过GET
的方式访问,那么示例代码:from django.views.decorators.http import require_http_methods
@require_http_methods
def my_view(request):
pass
django.view.decorators.http.require_GET
: 这个装饰器相当于是require_http_methods(['GET'])
的简写形式,只允许使用GET
的method
来访问视图;示例代码如下:from django.views.decorators.http import require_GET
@require_GET
def my_view(request):
pass
post
的方式来访问method
视图,示例代码如下:from django.views.decorators.http import require_POST
@require_POST
def my_view(request):
pass
django.views.decorators.http.require_safe
:这个装饰器相当于是require_http_methods(['GET','HEAD'])
的简写形式,只允许使用相对安全的方式来访问视图。因为GET和HEAD不会对服务器产生增删改的行为。因此是一种相对安全的请求方式。示例代码如下:from django.views.decorators.http import require_safe
@require_safe
def my_view(request):
pass
在Django中,重定向是使用redirect(to,*args,permanent=False, **kwargs)
来实现。to
是一个url,permanent
代表的是重定向是否是一个永久的重定向,默认false
,关于重定向的使用:
from django.shortcuts import reverse,redirect
def profile(request):
if requst.GET.get("username"):
return HttpResponse("%s,欢迎来到个人中心页面!")
else:
return redrect(reverse("urer:login"))
get
方法:用来获取指定key的值,如果没有这个key,那么会返回None。getlist
方法:如果浏览器上传上来的key对应的值有多个,那么就需要通过这个方法来获取。text/htm
def index(request):
response = HttpResponse('知了课堂
', content_type="text/plain; charset=utf-8") # content_type设置格式
response.status_code = 400 # 设置状态码
response['password'] = 'zhishao' # 设置响应头
response.write('alsd')
return response
dump
成json字符串,然后返回将json字符串封装成response对象返回给浏览器。并且它的conten_type是application/json
。
def jsonresponse(request):
person = {
'username': 'zhiliao',
'age': 18,
'height': 180
}
# 不使用JsonResponse的代码
# person_str = json.dumps(person)
# response = HttpResponse(person_str, content_type='application/json')
# return response
# 使用JsonResponse的代码
response = JsonResponse(person)
return response
# 默认情况下sonResponse只能对字段进行dump,如果相对非字典的数据进行JsonResponse,那么需要传递一个`safe=False`参数。
person = [1,2,3,4,5]
return HttpResponse(person, safe=false)
def csv1(request):
response = HttpResponse(content_type='text_csv')
# 指定下载文件名
response['Content-Disposition'] = "attacgment;filename = 'abc.csv'"
writer = csv.writer(response) # 往writer写入就会写入response
writer.writerow(['username', 'age'])
writer.writerow(['zhiliao', 18])
return response
def template_csv(request):
response = HttpResponse(content_type='text/csv')
# 指定下载文件名
response['Content-Disposition'] = "attachment;filename ='abc.csv'"
context = {
'rows': [
['username', 'age'],
['zhiliao', 18],
]
}
template = loader.get_template('abc.txt')
csv_template = template.render(context)
response.content = csv_template
return response
在写视图的时候,Django除了使用函数作为视图,也可以使用类作为视图。使用类视图可以使用类的一些特性,比如继承等。
from django.views.generic.base import View
是主要的类视图,所有的类视图都是基础自他。如果写自己的类视图,也可以继承自它。然后再根据当前请求的method
,来实现不同的方法。比如这个视图只能使用get方式来请求,那么就可以在这个类中定义get(self,request,*args,**kwargs)
方法。以此类推,如果只需要实现post
方法,那么就只需要在类中实现post(self,request,*args,**kwargs)
,示例代码如下:class DefineClassview(View):
"""演示类视图的定义和使用"""
def get(self, request,*args,**kwargs):
"""处理GET请求业务逻辑"""
return HttpResponse('GET请求业务逻辑')
def post(self, request,*args,**kwargs):
"""处理POST请求业务逻辑"""
return HttpResponse('POST请求业务逻辑')
def put(self, request):
pass
在配置路由时,需要使用类视图的as_view()l来注册添加:
urlpatterns = [
# 视图函数:注册
# url(r'^register/$', views.register, name='register'),
# 类视图:注册 as_view()可以将类视图转换成视图,并决定如何分发请求
url(r'^register/$', views.RegisterView.as_view(), name='register'),
]
示例:
class BookDetaialView(View):
def post(self,request,book_id):
return HttpResponse('图书id是:{}'.format(book_id))
def http_method_not_allowed(self, request, *args, **kwargs):
return HttpResponse('你使用的是%s请求,但是不支持POST以外的其他请求!'%request.method)
然后在urls中添加映射:
path('detaial/
当我们输入网址进行访问的时候,就会返回一个字符串:你使用的是GET请求,但是不支持POST以外的其他请求!
其实不管是get请求还是post请求,都会走django.views.generic.base.View中dispatch(request,*args,**kwargs)方法,所以如果实现这个方法,将能够对所有请求都处理到。
template_name
,这个属性是用来存储模板的路径,templateView
会自动的渲染这个变量指向的模板。另外一个是get_context_data
,这个方法是用来返回上下文数据的,也就是在给模板传的参数的。示例代码如下:from django.views.generic.base import TemplateView
class HomePageView(TemplateView):
template_name = "home.html"
def get_context_data(self, **kwargs)
context = super().get_context_data(**kwargs)
context["username"] = "看看看"
return context
在urls.py
中的映射代码如下:
from django.urls import path
from myapp.views import HomePageView
urlpatterns = [
path('', HomePageView.as_view())
]
如果在模板中不需要传递任何参数,那么可以直接只在urls.py
中使用TemplateView
来渲染模板。示例代码如下:
from django.urls import path
from django.views.generic import TemplateView
urlpatterns = [
path('', TemplateView.as_view(template_name="需要渲染的模板"))
]
ListView
class articleListview(ListView): # 必须继承ListView
model = Atricle # 重写model类属性,指定这个列表是给哪个模型的
template_name = 'atrophy.html' # 指定这个列表的模板
context_object_name = 'articles' # 指定这个列表模型在模板中的参数名称
paginate_by = 10 # 指定这个列表一页中展示多少条数据
ordering = 'creat_time' # 指定这个列表的排序方式
page_kwarg = 'p' # 获取第几页的数据的参数名称。默认是page
def get_context_data(self, **kwargs):
"""获取上下文的数据 """
context = super(articleListview, self).get_context_data(*kwargs) # 直接调用articListview
context['username'] = "zhiliao"
print(context)
return context
def get_queryset(self):
"""如果你提取数据的时候,并不是要把所有数据都返回,那么你可以重写这个方法。将一些不需要展示的数据给过滤掉。"""
return Atricle.objects.filter(id__lt=9)
Paginator和Page类
和Page
类都是用来做分页的,在Django中的路径为from django.core.paginator import Paginator
和from django.core.paginator import Page
。
count
:总共有多少数据num_pages
:总共有多少页page_range
:页面的区间。比如有三页,那么就range(1,4)有时候需要给一些视图添加装饰器。如果用函数视图那么非常简单,只要在函数的上面写上装饰器就可以了。但是如果想要给类添加装饰器,那么可以通过以下两种方案来实现
from django.utils.decorators import method_decorator
def login_required(func):
def wrapper(request,*args,**kwargs):
if request.GET.get("username"):
return func(request,*args,**kwargs)
else:
return redirect(reverse('index'))
return wrapper
class IndexView(View)
def get(self, request, *args, **kwargs):
return HttpResponse("index")
@method_decorator(login_required)
def dispatch(self, request, *args, **kwargs):
super(IndexView,self).dispatch(request, *args, **kwargs)
直接装饰在整个类上
from django.utils.decorators import method_decorator
def login_required(func):
def wrapper(request,*args,**kwargs):
if request.GET.get("username"):
return func(request,*args,**kwargs)
else:
return redirect(reverse('login'))
return wrapper
@method_decorator(login_required,name='dispatch')
class IndexView(View):
def get(self,request,*args,**kwargs):
return HttpResponse("index")
def dispatch(self, request, *args, **kwargs):
super(IndexView, self).dispatch(request,*args,**kwargs)
对于404和500这种自动抛出的错误。我们可以直接在templates文件夹下新建相应错误代码的模板文件。而对于其他的错误,我们可以专门定义一个app,用来处理这些错误。
def view_403(request):
return render(request, 'errors/403.html',status=403)
def view_403(request):
return render(request, 'errors/500.html',status=500)