八、模板层(二)

一、全局上下文

#### 实现步骤

1. 应用包下创建my_context_processor.py文件
```
#coding=utf-8
def mydata(request):
    return {'uname':'zhangsan'}

```
2. settings中配置当前函数路径
```
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')]
        ,
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
                'stu.my_context_processor.mydata'
            ],
        },
    },
]

```
3. 创建视图函数接收数据
```
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.http import HttpResponse
from django.shortcuts import render
# Create your views here.
from student.my_context_processor import mydata

def index_view(request):
    from  django.template import Template, RequestContext
    t = Template('hello:{{uname}}')
    render_string = t.render(RequestContext(request, dict_=None, processors=(mydata,)))
    return HttpResponse(render_string)
```

4. 直接在模板页面接收数据
```
{{uname}}
```
 二、csrf原理
 
#### CSRF(Cross Site Request Forgery, 跨站请求伪造)
CSRF(Cross Site Request Forgery, 跨站域请求伪造)是一种网络的攻击方式,它在 2007 年曾被列为互联网 20 大安全隐患之一。其他安全隐患,比如 SQL 脚本注入,跨站域脚本攻击等在近年来已经逐渐为众人熟知,很多网站也都针对他们进行了防御。然而,对于大多数人来说,CSRF 却依然是一个陌生的概念。即便是大名鼎鼎的 Gmail, 在 2007 年底也存在着 CSRF 漏洞,从而被黑客攻击而使 Gmail 的用户造成巨大的损失。

#### Django的解决方法

Django预防CSRF攻击的方法是在用户提交的表单中加入一个csrftoken的隐含值,这个值和服务器中保存的csrftoken的值相同,这样做的原理如下:
1. 在用户访问django的可信站点时,django反馈给用户的表单中有一个隐含字段csrftoken,这个值是在服务器端随机生成的,每一次提交表单都会生成不同的值
2. 当用户提交django的表单时,服务器校验这个表单的csrftoken是否和自己保存的一致,来判断用户的合法性
3. 当用户被csrf攻击从其他站点发送精心编制的攻击请求时,由于其他站点不可能知道隐藏的csrftoken字段的信息这样在服务器端就会校验失败,攻击被成功防御
#### Django防攻击策略
1. 不推荐禁用掉django中的CSRF。
2. 我们可以再html页面的form表单中添加csrf_token,带着表单的请求一起发送到服务器去验证。
```
<form action  method="post" >
    {% csrf_token %}
</form>
```  
3. 在后端一定要使用render()的方法返回数据。
```
return render(request, 'index.html', {'hello': '123})
全局:
中间件 django.middleware.csrf.CsrfViewMiddleware
局部:
@csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。
@csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。
exempt:免除
注意:from django.views.decorators.csrf import csrf_exempt,csrf_protect
```
三、中间件
#### 实现步骤
1. 项目根目录下创建python package
2. 自定义一个python文件
```
#coding=utf-8
from django.utils.deprecation import MiddlewareMixin
class Row1(MiddlewareMixin):
    def process_request(self, request):
        print("中间件1")
    def process_response(self, request, response):
        print("中间件1返回")
        return response
# 参数里的 response :就是views里面返回的值,所以要继续返回一下,否则客户端收不到数据
class Row2(MiddlewareMixin):
    def process_request(self, request):
        print("中间件2")
       
    def process_response(self, request, response):
        print("中间件2返回")
        return response
class Row3(MiddlewareMixin):
    def process_request(self, request):
        print("中间件3")
    def process_response(self, request, response):
        print("中间件3返回")
        return response
```

3. settings文件中配置自定义中间件
```
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'middle.my.Row1',
    'middle.my.Row2',
    'middle.my.Row3',
]
```

4. 配置URL
```
from django.conf.urls import url, include
from django.contrib import admin
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^student/', include('student.urls')),
]

#coding=utf-8
from django.conf.urls import url
import views
urlpatterns=[
    url(r'^$',views.IndexView.as_view()),
  
]
```
5.创建视图
```
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.http import HttpResponse
from django.views import View
# Create your views here.
class IndexView(View):
    def get(self,request,*args,**kwargs):
        print u'最终返回值'
        return HttpResponse('OK')
       
```
6. 浏览器访问:http://127.0.0.1:8000/student/
7. 运行结果:
```
中间件1
中间件2
中间件3
最终返回值
中间件3返回
中间件2返回
中间件1返回
```
 四、admin后台类
#### 配置模型类
```
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
# Create your models here.
from django.contrib.auth.models import User
from django.utils import timezone

class BlogArticles(models.Model):
    title = models.CharField(max_length=300)
    author = models.ForeignKey(User,related_name='blog_posts')
    body = models.TextField()
    publish = models.DateTimeField(default=timezone.now)
    class Meta:
        ordering = ('-publish',)

    def __unicode__(self):
        return self.title
 
```
#### 配置admin后台类
```
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.contrib import admin
# Register your models here.
from .models import BlogArticles
class BlogArticlesAdmin(admin.ModelAdmin):
    #显示表格列表字段
    list_display = ('title','author','publish',)
    #条件查询字段
    list_filter = ('publish','author',)
    #搜索框中根据某些字段进行查询
    search_fields = ('title','body')
    # 在admin后台类中加入raw_id_fields(只适用于外键)后,会显示外键的详细信息
    raw_id_fields = ("author",)
    #以某个日期字段分层次查询
    date_hierarchy = 'publish'
    #排序字段
    ordering = ['publish','author']
admin.site.register(BlogArticles,BlogArticlesAdmin)
```
hierarchy:层级
#### 终端创建超级用户
```
python manage.py createsuperuser

```

#### 浏览器访问
```
http://127.0.0.1:8000/admin
``` 
posted @ 2020-05-31 10:25  小熊尤里  阅读(115)  评论(0编辑  收藏  举报