随便写点

  布局响应式

  响应式就是浏览器随着边框的缩小会产生的浏览样式的变化。

@media (max-width: 700px) {
       .jeff{
       width: 100%;
       height: 100px;
       background-color: yellow;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
                .jeff{
            width: 100%;
            height: 100px;
            background-color: red;
        }
        @media (max-width: 700px) {
                    .jeff{
            width: 100%;
            height: 100px;
            background-color: yellow;
        }
        }

    </style>
</head>
<body>
    <div class="jeff">love</div>
</body>
</html>
响应式test

  当然也可以使用bootstrap里封装好的导航条等代码,其完成响应式的方法也是基于@media完成的。

  栅格系统

  bootstrap把页面分为12个大格子,使用.col-md-8的方式就可以轻松的把页面划分开。一共有四种方式划分,根据显示屏幕的像素大小分别为.col-xs-<.col-sm-<.col-md-<.col-lg-。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <title></title>

    <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css"/>
</head>
<body>

    <div style="background-color: #dddddd">
        <div class="col-lg-1">左边</div>
        <div class="col-lg-11">右边</div>
    </div>
    <div style="background-color: #dddddd">
        <div class="col-md-1">左边</div>
        <div class="col-md-11">右边</div>
    </div>
    <div style="background-color: #dddddd">
        <div class="col-sm-1">左边</div>
        <div class="col-sm-11">右边</div>
    </div>
    <div style="background-color: #dddddd">
        <div class="col-xs-1">左边</div>
        <div class="col-xs-11">右边</div>
    </div>
</body>
</html>
栅格系统

  栅格也是根据响应式做的大小调整。

  不允许缩放的栅格:

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">

   hover:

  之前做的鼠标悬浮外层div使子层发生样式改变都是使用js来完成的,其实可以直接使用hover来完成:

外层:hover 要改变的里层{悬浮后的样式}
        .pg-header .avatar .user-info{
            display: none;
            background-color: white;
            border: 1px solid #dddddd;
            position: absolute;width: 200px;top: 48px;right: 2px;color: white;z-index: 100;
        }
        .pg-header .avatar:hover .user-info{
            display: block;
hover

  html模板渲染

#后台视图函数
def test(request):
    return render(request,'test.html',{'k1': 1,'k2': 'uuu'})

#前端test.html
<body>
    <h1>{{ k1 }}</h1>
    <h1>{{ k2 }}</h1>

    <script>
        alert('{{ k2 }}');//uuu
        alert({{ k2 }});//uuu not define
    </script>
</body>

  后端一定是先将html文件渲染以后再发送给客户端浏览器,{{k2}}在后端被渲染成uuu,前者以字符串形式发出,后者则被前端认为是变量未定义报错。

  Cookie

  简单的理解为保存在浏览器端“键值对”,用于解决http无状态短连接的问题,发送Http请求时,在请求头中携带当前所有可访问的cookie。

def login(request):
    if request.method == "GET":
        return render(request,'login.html')
    else:
        user = request.POST.get('username')
        pwd = request.POST.get('password')
        if user == 'alex' and pwd == '123':
            obj = redirect('/classes/')
            obj.set_cookie('ticket',"123123")#设置cookie
            return obj
        else:
            return render(request,'login.html')

//登陆的页面视图函数可以接收头部的cookie
    # 去请求的cookie中找凭证
    tk = request.COOKIES.get('ticket')print(tk)
    if not tk:
        return redirect('/login/')

  set_cookie可以有很多的参数:

  max_age,存在时长单位s。超过时间就自动失效。

  expires与max_age意义相同,只是它用于指定具体的时间。相比较而言,max_age更常用。

def login(request):
    if request.method == "GET":
        return render(request,'login.html')
    else:
        user = request.POST.get('username')
        pwd = request.POST.get('password')
        if user == 'alex' and pwd == '123':
            obj = redirect('/classes/')
            import datetime
            from datetime import timedelta
            ct = datetime.datetime.utcnow()#当前时间
            v= timedelta(seconds=10)#往后延迟10s
            value = ct + v
            # obj.set_cookie('ticket',"asdasdsd",max_age=10)
            obj.set_cookie('ticket',"asdasdsd",expires=value)
            return obj
        else:
            return render(request,'login.html')
expires

  path,指定cookie生效的url,默认是path(/),在整个路径下都生效。

  domain,指定域名访问。

   secure=False,httponly=False部分安全操作,httponly只能自Http请求中传入,js代码无法获取到(抓包依然可以获取),secure是控制Https操作。

  cookie签名(类似加盐)

obj.set_signed_cookie('ticket',"123123",salt='jjjjjj')
request.get_signed_cookie('ticket',salt='jjjjjj')

   xss攻击

  xss就是在网页评论等input框里,写入js语句,从而控制得到后台cookie等操作。django默认是可以阻止xss攻击的。

  但是我们有时还是需要使用到传入html语句的。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <h1>评论</h1>
    {% for item in msg %}
        <div>{{ item|safe }}</div>
    {% endfor %}
</body>
</html>
|safe 可以生效
def test(request):
    from django.utils.safestring import mark_safe
    temp = "<a href='http://www.baidu.com'>百度</a>"
    newtemp = mark_safe(temp)
    return render(request,'test.html',{'temp':newtemp})
后端导入mark_safe

  如果你做了操作放行了xss,那么你一定要在后台做过滤来保证你的安全。

def comment(request):
    if request.method == "GET":
        return render(request,'comment.html')
    else:
        v = request.POST.get('content')
        if "script" in v:
            return render(request,'comment.html',{'error': '小比崽子还黑我'})
        else:
            msg.append(v)
            return render(request,'comment.html')
过滤掉关键字

   CSRF

  简单的来说就是在页面生成随机字符串来帮助确认用户身份的(用户下一次登陆就会带着这个字符串)。

  django默认开启了CSRF功能,在页面写上{% csrf_token %},浏览器就会渲染成

<input type="hidden" name="csrfmiddlewaretoken" value="HJ5pKbvzGcCMeBYSm37ceuTXraBe6ZTi5xS2d0desCTU9iglNcIBtTEIdYVY28Bp">
csrf

  同时,在cookie中也有这个字符串。

  要想全栈都禁用csrf就要在settings.py中直接注释掉。

  局部禁用csrf要使用装饰器@csrf_exempt:

            from django.views.decorators.csrf import csrf_exempt

            @csrf_exempt
            def csrf1(request):

                if request.method == 'GET':
                    return render(request,'csrf1.html')
                else:
                    return HttpResponse('ok')
局部禁用

  局部使用,全局下要禁用,只在使用的函数前加装饰器@csrf_protect:

            # 'django.middleware.csrf.CsrfViewMiddleware',
            
            from django.views.decorators.csrf import csrf_exempt,csrf_protect

            @csrf_protect
            def csrf1(request):

                if request.method == 'GET':
                    return render(request,'csrf1.html')
                else:
                    return HttpResponse('ok')
局部使用

  CBV添加装饰器的方式

CBV:
    from django import views
    from django.utils.decorators import method_decorator

    @method_decorator(auth,name='dispatch')
    class Order(views.View):

        # @method_decorator(auth)
        # def dispatch(self, request, *args, **kwargs):
        #     return super(Order,self).dispatch(request, *args, **kwargs)

        # @method_decorator(auth)
        def get(self,reqeust):
            v = reqeust.COOKIES.get('username111')
            return render(reqeust,'index.html',{'current_user': v})

        def post(self,reqeust):
            v = reqeust.COOKIES.get('username111')
            return render(reqeust,'index.html',{'current_user': v})
from django.views import View
from django.utils.decorators import method_decorator

@method_decorator(csrf_protect,name='dispatch')#name是使用的函数名
class Foo(View):
    
    def get(self,request):
        pass

    def post(self,request):
        pass
CBV禁用csrf

   如果网站有csrf,那么往后台发Ajax时也必须要把csrf传到后台。除了把标签里的input中的csrf以data传到后台,还可以通过cookie的方式传递。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <form method="POST" action="/csrf1.html">
        {% csrf_token %}
        <input id="user" type="text" name="user" />
        <input type="submit" value="提交"/>
        <a onclick="submitForm();">Ajax提交</a>
    </form>
    <script src="/static/jquery-1.12.4.js"></script>
    <script src="/static/jquery.cookie.js"></script>{#  jQuery简单获取cookie的插件#}

    <script>
        function submitForm(){
            var token = $.cookie('csrftoken');
            var user = $('#user').val();
            $.ajax({
                url: '/csrf1.html',
                type: 'POST',
                headers:{'X-CSRFToken': token},//只能放在请求头里传到后台,X-CSRFToken名字不能改
                data: { "user":user},
                success:function(arg){
                    console.log(arg);
                }
            })
        }
    </script>
</body>
</html>
cookie传递csrf的值

  $.cookie('csrftoken')可以取到cookie的值,还可以设置cookie的值$.cookie('csrftoken','123123'),cookie的值还可以是很多。

  admin管理

  django自带了数据库后台管理,我们使用

python manage.py createsuperuser

  设置用户账号与密码就可以登陆进后台。

  操作的表要在admin.py中注册:

from django.contrib import admin
from app01 import models
admin.site.register(models.UserInfo)

   MVC与MTV

  这两者其实是一个概念,MVC是models(数据库,模型),views(html模板),controllers(业务逻辑处理)。而MTV则是换了个名称models(数据库,模型),templates(html模板),views(业务逻辑处理)。django使用的就是MTV的逻辑。

  django的生命周期

  web框架的本质是socket,我们使用的django从本质上上来说是wsgi(wsgiref模块或其他wsgi模块)与django两部分组成。

Wsgi+Django
    from wsgiref.simple_server import make_server
     
     
    def RunServer(environ, start_response):

        Django框架开始
        中间件
        路由系统
        视图函数
        。。。。。
        
        start_response('200 OK', [('Content-Type', 'text/html')])
        
        
        return [bytes('<h1>Hello, web!</h1>', encoding='utf-8'), ]
     
     
    if __name__ == '__main__':
        httpd = make_server('127.0.0.1', 8000, RunServer)
        httpd.serve_forever()

  中间件

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
class M1(MiddlewareMixin):
    def process_request(self,request):
        print('m1.process_request')

    def process_view(self, request, callback, callback_args, callback_kwargs):
        print('m1.process_view')
        # response = callback(request,*callback_args,**callback_kwargs)
        # return response

    def process_response(self,request,response):
        print('m1.process_response')
        return response

    def process_exception(self, request, exception):
        print('m1.process_exception')

    def process_template_response(self,request,response):
        """
        视图函数的返回值中,如果有render方法,才被调用
        :param request:
        :param response:
        :return:
        """
        print('m1.process_template_response')
        return response
创建中间件

  创建完在配置中注册即可生效。process_request与请求信息相关,若定义返回值,则直接从此中间件的response返回。process_view与视图有关,若有返回值,直接跳过剩下的中间件的process_view函数,从最后一个response返回,process_exception,出错时才会触发,并且跳过之后所有process_exception,从最后一个response返回。process_response有返回值,并且直接从最后一个response返回。

class JSONResponse:
    def __init__(self,req,status,msg):
        self.req = req
        self.status = status
        self.msg = msg
    def render(self):#有render方法才能触发
        import json
        ret = {
            'status': self.status,
            'msg':self.msg
        }
        return HttpResponse(json.dumps(ret))

def test(request):
    return JSONResponse(request,True,"错误信息")
process_template_response

   中间件是为了对所有请求或一部分请求做批量处理的。

posted @ 2017-12-24 22:46  JeffD  阅读(273)  评论(0编辑  收藏  举报