* django 限制请求
* 页面重定向
* HttpRequest对象
* 生成CSV文件
* 类视图
## django 限制请求
* get 一般用来像服务器索取数据 不会对服务器的状态进行修改 不会像服务器提交数据
* post 一般用来像服务器提交数据 会对服务器的状态进行修改 比如提交一片文章给服务器
~~~
**装饰器:require_http_method()
使用Django预置的require_http_methods(methods)装饰器进行限制, 让框架帮你拦截那些不想要的请求。
405代码表示:请求的方法 不被允许。
require_GET() - 声明被装饰的视图仅支持GET方法
require_POST() - 声明被装饰的视图仅支持POST方法
require_SAFE() - 声明被装饰的视图仅支持GET和HEAD方法
~~~
```
from django.views.decorators.http import require_http_methods
@require_http_methods(['GET']) 这样的话只能 GET请求过来
def index(request):
#首页用来展示数据
#一般用get请求 展示数据
articles = Article.objects.all()
return render(request,'index.html',context={"articles":articles})
完整实例
models.py
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
price = models.FloatField(default=0)
create_time = models.DateTimeField(auto_now_add=True)
class Meta:
db_table = 'article'
views.py
from django.shortcuts import render
from .models import Article
from django.views.decorators.http import require_http_methods,require_GET,require_POST,require_safe
from django.http import HttpResponse
def add(request):
books = Article(title='三国',content='haha')
books.save()
return HttpResponse("添加成功")
#两种方法判断method请求方法
# @require_GET
@require_http_methods(['GET'])
def index(request):
article = Article.objects.all()
for i in article:
print(i.title)
return render(request,'index.html',context={"article":article})
@require_http_methods(['GET','POST'])
def add_article(request):
if request.method == "GET":
return render(request,'add_article.html')
else:
title = request.POST.get('title')
content = request.POST.get('content')
price = request.POST.get('price')
#第一种方法添加数据
Article.objects.create(title=title,content=content,price=price)
#第二种方法添加数据
a = Article(title=title,content=content,price=price)
a.save()
return HttpResponse("添加成功")
add_article.html
<form action="{% url 'add_article' %}" method="get">
<table>
<tbody>
<tr>
<td>标题</td>
<td><input type="text" name="title"></td>
</tr>
<tr>
<td>内容</td>
<td><input type="text" name="content"></td>
</tr>
<tr>
<td>价格</td>
<td><input type="text" name="price"></td>
</tr>
<tr>
<td></td>
<td><input type="submit" name="提交"></td>
</tr>
</tbody>
</table>
</form>
```
## 页面重定向
* 301 永久性重定向 比如 t.tt 跳转到 https://www.smartisan.com/ www.jingdong.com 跳转到 www.jd.com
* 302暂时性的重定向 https://www.zhihu.com 如果没有登陆 跳转到 https://www.zhihu.com/signup?next=%2F
## HttpRequest对象
```
django在接收到http请求以后 会根据请求携带的参数 及 报文 创建 一个 WSGIRequest对象 这个对象会作为视图函数的第一个参数传递给 视图函数 也就是经常看到的request
```
### WSGIRequest 属性
* path request.path 请求服务器的完整的路径 注意这里不包括域名和端口号
* method request.method 请求的方法 GET 或者 POST
* request.get_raw_uri() 包含域名和端口
* http://127.0.0.1:9000/signup/?username=1111&password=12345
* request.get_host() 返回的是127.0.0.1
~~~
代码实例
views.py
from django.shortcuts import render,redirect,reverse
from django.http import HttpResponse
from django.core.handlers.wsgi import WSGIRequest
# Create your views here.
# def index(request):
# username = request.GET.get('username')
# if username:
# return HttpResponse("首页")
# else:
# return redirect(reverse('signup'))
#
# def signup(request):
# return HttpResponse("登录界面")
def index(request):
print(type(request))#打印出<class 'django.core.handlers.wsgi.WSGIRequest'>
print(request.path)#打印出 /
return HttpResponse("首页")
def signup(request):
print(request.path)#打印出/signup/
print(request.method)#打印出GET
print(request.get_raw_uri())#打印出http://127.0.0.1:9000/signup/
print(request.get_host())#打印出127.0.0.1:9000
return HttpResponse("登录首页")
主目录下的urls.py
from front import views
urlpatterns = [
path('', views.index,name='index'),
path('signup/', views.signup,name='signup'),
]
~~~
## 将数据到处到 CSV 文件
```
from django.http import HttpResponse
import csv
def index(request):
response = HttpResponse(content_type='text/csv') #告诉浏览器这是一个 csv 格式的文件 不是html 如果不指定 就是html
response['Content-Disposition']="attechment;filename='abc.csv'"# 在 response 添加一个 'Content-Disposition'头 这样的话 是为了告诉他 该怎么样处理这个csv文件 attechment 说明这是一个附件 这样浏览器就不会显示它 而是下载 filename='abc.csv' 是指定附件的名字
writer = csv.writer(response) writer 将 内容写进respone
writer.writerow(['username','age','height'])
writer.writerow(['qulinx', '18', '181cm'])
return response
```
### 根据模板 导出 csv 文件
```
def template_csv_view(request):
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = "attechment;filename='linzhen.csv'"
context = {
'rows':[
['username','age','height','weight'],
['zelinx',18,'181cm','90kg']
]
}
#获得模板python1806.txt
template= loader.get_template('python1806.txt')
csv_template = template.render(context)
response.content = csv_template
return response
```
### StreamingHttpResponse 在处理大文件的时候 不会因为 服务器响应时间长而超时 这个类不继承于 HttpResponse 类似于 大视频 边看边下载
```
def large_csv_view(request):
# response = HttpResponse(content_type='text/csv')
# response['Content-Disposition'] = "attechment;filename='linzhen.csv'"
# writer = csv.writer(response)
# for row in range(0,1000000):
# writer.writerow(['Row {}'.format(row),'{}'.format(row)])
# return response
response = StreamingHttpResponse(content_type='text/csv')
response['Content-Disposition'] = "attechment;filename='kangbazi.csv'"
rows = ("第{},{}\n".format(row,row) for row in range(0,10000000))
response.streaming_content=rows
return response
```
## 类视图
```
views.py
from django.views.generic import View
class AddFront(View):
def get(self,request,*args,**kwargs):
#*args 所有的位置参数 **kwargs 所有的关键字参数
# 这两个说明 你可以接收任意的参数
#self 这个参数是对象的参数
return render(request,'add_book.html')
def post(self,request,*args,**kwargs):
title = request.POST.get('title')
content = request.POST.get('content')
print("title:{},content:{}".format(title,content))
return HttpResponse("添加成功")
urls
path('add/',views.AddFront.as_view(),name="add_front")
```
## TemplateView 返回模板用 比如果壳网 的 关于我们 这个网页完全可以是 静态的 可以直接返回 不用每次请求 请求数据库 之类的
```python
class AboutView(TemplateView):
template_name = 'about.html'
urls.py
path('about',views.AboutView.as_view(),name="about_view"),
如果想要加载动态内容
只需要
class AboutView(TemplateView):
template_name = 'about.html'
def get_context_data(self, **kwargs):
context = {
"phone":"13888888888"
}
return context
页面上:
{{phone}}
```
~~~
完整代码实例
views.py
from django.shortcuts import render
from .models import Front
from django.http import HttpResponse
from django.views.generic import View,TemplateView
# Create your views here.
def add_front(request):
fronts = []
for a in range(0,100):
front = Front(title='标题:%s'%a,content='内容:%s'%a)
fronts.append(front)
Front.objects.bulk_create(fronts)#保存数据
return HttpResponse("添加成功")
class AddFront(View):
def get(self,request,*args,**kwargs):
return render(request,'add_book.html')
def post(self,request,*args,**kwargs):
title = request.POST.get('title')
content = request.POST.get('content')
create_time = request.POST.get('create_time')
print("title:{},content:{},创建时间:{}".format(title,content,create_time))
front = Front(title=title,content=content,create_tme=create_time)
front.save()
return HttpResponse("添加成功")
class AboutView(TemplateView):
template_name = 'about.html'
def get_context_data(self, **kwargs):
context = {
"phone":"13888888888888888"
}
return context
models.py
from django.db import models
# Create your models here.
class Front(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
create_tme = models.DateTimeField(auto_now_add=True)
class Meta:
db_table = 'front'
app下的urls.py
from django.urls import path
from . import views
urlpatterns = [
path('',views.add_front),
path('add/',views.AddFront.as_view(),name='add_front'),
path('about/',views.AboutView.as_view(),name='about_view'),
]
项目下的urls.py
from django.urls import path,include
urlpatterns = [
path('front/', include('front.urls')),
]
~~~