Frank的学习之路

Day_20_总结_ORM使用和安全防护

目录

-Day20-ORM使用和安全防护

[1].创建表方法一

[2].创建表方法二

[3].创建表方法三:自关联

[4].FK关联

[5]. 普通索引和字段

[6]. EmailField使用和django管理员配置

[7].设置字段属性和索引

[8]. 安全方便:js脚本攻击

[9]. 安全方便:csrf:跨站请求伪造

[10]. 模板使用

[11]. session使用

[12]. yaf的介绍


-s2day20-settings.py


先注释下面的一行代码

MIDDLEWARE = [
    # 'django.middleware.csrf.CsrfViewMiddleware',
]


添加静态文件路径

STATICFILES_DIRS=(     os.path.join(BASE_DIR,'static'),

)


-s2day20-urls.py

配置访问路径,然后初始化

from app01 import views



urlpatterns = [     url(r'^admin/', admin.site.urls),     url(r'^test/', views.test),

]


[1].创建表方法一:

-app01-models.py

构建表结构,然后初始化

from django.db import models # Create your models here. class Boys(models.Model):     #不写id,默认创建一个字段名为id的自增主键     username=models.CharField(max_length=32,null=False,default='')     nickname=models.CharField(max_length=32,null=False,default='')     age=models.IntegerField(null=False,default='') class Girls(models.Model):     username=models.CharField(max_length=32,null=False,default='')     nickname=models.CharField(max_length=32,null=False,default='')     age=models.IntegerField(null=False,default='') class Boys2Girls(models.Model):     b=models.ForeignKey('Boys',on_delete=None)     g=models.ForeignKey('Girls',on_delete=None)

初始化:

python3 manage.py makemigrations  //执行生成sql文件

python3 manage.py migrate //执行文件


pycharm的sqlite3连接方法:

https://jingyan.baidu.com/article/e5c39bf5e4f32439d7603387.html

-app01-views.py

反向查找海峰有几个女朋友:

from django.shortcuts import render,HttpResponse from app01 import models def test(request):     #第一种解法:     #和海峰有关系的女的     res=models.Boys.objects.filter(username='hf').first()     # print(res)     # print(res.username,res.nickname)     #Boys object     #反向查找     #res.小写类名_set().all()     #<QuerySet [<Boys2Girls: Boys2Girls object>,               # <Boys2Girls: Boys2Girls object>,              # <Boys2Girls: Boys2Girls object>]>     info=res.boys2girls_set.all()     for item in info:         #正向查询         print(item.g.username)     print(info)     return HttpResponse('ok')




第二种解法:
正向查找海峰有几个女朋友 from django.shortcuts import render,HttpResponse from app01 import models def test(request):     res = models.Boys2Girls.objects.filter(b__username='hf')     print(res)     for item in res:         # 正向查询         print(item.g.username)     print(res)     return HttpResponse('ok')

关联关系查询

-app01-models.py

修改related_name='girls' related_name='boys' 参数

from django.db import models

class Boys2Girls(models.Model):     b=models.ForeignKey('Boys',on_delete=None,related_name='girls')     g=models.ForeignKey('Girls',on_delete=None,related_name='boys')

-app01-views.py

修改下面参数

related_name='girls'

info=res.girls.all()
related_query_name='girls'
info=res.girls_set.all()


[2].创建表方法二:


使用manytomanyfiled生成关系表appo1_girls_b,并添加数据

生成关系表appo1_girls_b

-app01-models.py

from django.db import models

class Boys(models.Model):
    #不写id,默认创建一个字段名为id的自增主键
   
username=models.CharField(max_length=32,null=False,default='')
    nickname=models.CharField(max_length=32,null=False,default='')
    age=models.IntegerField(null=False,default='')

class Girls(models.Model):
    username=models.CharField(max_length=32,null=False,default='')
    nickname=models.CharField(max_length=32,null=False,default='')
    age=models.IntegerField(null=False,default='')
    b=models.ManyToManyField("Boys")

1.manytomanyfiled在关系表appo1_girls_b添加数据

-app01-views.py

def test(request):
 
   
res=models.Girls.objects.filter(id=1).first()
    res.b.add(2)
    res.b.add(3,4)
    res.b.add(*[1,2])

    return HttpResponse('ok')

2.manytomanyfiled在关系表appo1_girls_b删除数据

def test(request):

   
res.b.remove(2)

    return HttpResponse('ok')

[3].创建表方法三:自关联

-app01-models.py

from django.db import models

class UserInfo(models.Model):
    username=models.CharField(max_length=32,null=False,default='')
    nickname=models.CharField(max_length=32,null=False,default='')
    age=models.IntegerField(null=False,default='')

    gender_choice=(
        (1,''),
        (2,''),
    )
    gender=models.IntegerField(choices=gender_choice)

class U2U(models.Model):
    b=models.ForeignKey('UserInfo',on_delete=None,related_name='girl')
    g=models.ForeignKey('UserInfo',on_delete=None,related_name='boy')

-app01-views.py

from django.shortcuts import render,HttpResponse
from app01 import models

def test(request):

   
res=models.UserInfo.objects.filter(username='hf').first()
    info=res.girl.all()
    for item in info:
        #正向查询
       
print(item.g.username)
    print(info)
    return HttpResponse('ok')

[4].FK关联

'''
id  new_id  comment   user  replay_id
1     1     
别逼逼   张三      0
2     1     
就比比   李四      0
3     2     
瞎比比   xxx       0
4     1      sssss    eagon     1
5     2      bbbbb    alex      3
'''
class Comment(models.Model):
    new_id=models.IntegerField(null=False,default=0)
    comment=models.CharField(null=False,max_length=256,default='')
    user=models.CharField(null=False,max_length=32,default='')
    replay_id=models.ForeignKey("comment",on_delete=None)

[5]. 普通索引和字段

db_index

举例:

username=models.CharField(max_length=32,default='',null=False,db_index=True)

字段:

SmallIntegerField    //小整数-32768~32767

IntegerField         //正整数(有符号)-2147483648~2147483647

PositiveIntegerField //正数 0~2147483647

BigIntegerField     

//长整数(有符号) -9223372036854775808~9223372036854775807

CharField  //字符类型 max_length表示字符长度

TextField   //文本类型


FloatField(Field)

    -浮点型

DecimalField(Field)

    -10进制小数

    -参数

    max_digits,小数总长度

    decimal_places,小数位长度


[6]. EmailField使用和django管理员配置

EmailField()

    在models中使用:

    email=models.EmailField()

    转换email varchar(254)modle模板中不起作用,在django管理里面有作用(正则表达式)

   

django的配置:

    -app01-admin.py中主编

       from app01 import models

       admin.site.register(models.Test)

    -s2day20-urls.py中,

       url(r'^admin/', admin.site.urls),

    -命令行创建超级管理员

       python3 manage.py createsuperuser


[7].设置字段属性和索引

null                数据库中字段是否可以为空

default            数据库中字段的默认值

primary_key         数据库中字段是否为主键

db_index           数据库中字段是否可以建立索引

unique             数据库中字段是否可以建立唯一索引

unique_for_date     数据库中字段[日期]部分是否可以建立唯一索引

unique_for_month    数据库中字段[]部分是否可以建立唯一索引

unique_for_year     数据库中字段[]部分是否可以建立唯一索引


在类中定义:

class Meta:
    #设置联合索引
   
index_together=(
        ('username','age')
    )
    unique_together=(
        ('username', 'age')
    )


[8]. 安全方便:js脚本攻击

    xss:跨站脚本攻击

    web网站:js脚本

    js脚本:

       <script>alert('123')</script>

    加了safe之后,取消了对数据的转义,所以慎用safe

    -攻击用处:

       -<script>alert('123')</script>

       -<script>document.cookies</script>


代码举例:

-s2day20-urls.py

urlpatterns = [
   
url(r'^test3/', views.test3),
    url(r'^index/', views.index),
]


-app01-views.py

msg=[]
def test3(request):
    if request.method=='GET':
        return render(request,'comment.html')
    else:
        comment=request.POST.get('comment')
        msg.append(comment)
        return render(request,'comment.html')

def index(request):

    return render(request,'index.html',{'msg':msg})


-templates-comment.html

<form action="/test3/" method="post">
    <input type="text" name="comment">
    <input type="submit" name="提交">
</form>


访问地址:http://127.0.0.1:8005/test3/


-templates-index.html

<h2>评论如下</h2>
{{ msg.0|safe }}


访问地址:http://127.0.0.1:8005/index/


[9]. 安全方便:csrf:跨站请求伪造

方法:

-加一串随机的字符串

只能防止一大部分人

django的方法:

    全站使用csrf验证:

    -开启'django.middleware.csrf.CsrfViewMiddleware',

    -html页面,开启token

    <form action="/csrf1/" method="post">

       {% csrf_token %}

       <input type="text" name="username">

       <input type="submit" value="提交">

    </form>

   

    全站使用csrf,但是局部业务函数不使用csrf:

    -开启'django.middleware.csrf.CsrfViewMiddleware',

    -针对局部业务函数,加上如下装饰器:

    from django.views.decorators.csrf import csrf_exempt,csrf_protect


    @csrf_exempt

    def csrf1(request):

       if request.method=='GET':

           return render(request,'csrf1.html')

       else:

           username=request.POST.get('username')

           return HttpResponse('ok')

          

    全站关闭csrf的验证,但是局部使用

    -关闭'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:

           username=request.POST.get('username')

           return HttpResponse('ok')


ajax方式提交数据:


-s2day20-urls.py

urlpatterns = [
        url(r'^csrf2/', views.csrf2),
]


-app01-views.py

def csrf2(request):
    if request.method=='GET':
        return render(request,'csrf_ajax.html')
    else:
        username=request.POST.get('username')
        return HttpResponse('ok')


-templates-csrf_ajax.html

<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="/static/jquery.min.js"></script>
</head>
<body>
<form action="">
    {% csrf_token %}
    <input type="text" name="username" id="username">
    <input type="button" value="提交" id="btn">
</form>
</body>


方式一:


<script>
    var csrf_token=$("input[name='csrfmiddlewaretoken']").val()
    console.log(csrf_token)

    $('#btn').click(function () {
        $.ajax({
            url:"/csrf2/",
            type:"POST",
data:{"username":$('username').val(),"csrfmiddlewaretoken":csrf_token},
            success:function (args) {
                console.log(args)
            }
        })
    })
</script>


方式二:

<script>
    var csrf_token=$("input[name='csrfmiddlewaretoken']").val()
    console.log(csrf_token)

    $('#btn').click(function () {
        $.ajax({
            url:"/csrf2/",
            type:"POST",
            headers:{'X-CSRFToken':csrf_token},
            data:{"username":$('username').val(),},

            success:function (args) {
                console.log(args)
            }
        })
    })
</script>


[10]. 模板使用

-现在用的模板语言都是django自带的模板语言

-jinjia2的模板语言

模板标签:

    字符串:{{name}}

    列表:{{myli.0}} {{myli.1}}

    字典:{{mydict['username']}}

    {%for item in res%} content {%endfor%}

    {%if true%}{%else%}

    母版和子版

    母版:

       {%block xxx%}{%endblock%}

    子版:

       {%extends muban.html%}

       {%block xxx%} content {%endblock%}


    内部过滤函数:

       {{ name }}

       {{item.event_start|date:"Y-m-d H:i:s"}}

       {{bio|truncatewords:"30"}}

       {{ name|first|upper }}

       {{ name|lower }}


自定义simple_filter:

1.在app中创建templatetags模块

-app01-templatetags-xx.py


2.在模块中创建任意.py文件,例如:xx.py

from django import template

register = template.Library()

@register.filter()
def my_upper(val):
    return val.upper()


-s2day20-urls.py

urlpatterns = [
        url(r'^test4/', views.test4),
]

-app01-views.py

def test4(request):
    name='Frank'
   
return render(request,'test4.html',{"name":name})

-templates-test4.html

{% load xx %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{{ name|first|upper }}
{{ name|lower }}
{{ name|my_upper }}
</body>
</html>


-simple_filter

@register.filter()

def my_upper(val,args):  //只能传2个参数

    return val + args

   

使用:

{% load xx %}

{{ name|my_upper:"sss" }}


-simple_tag

@register.simple_tag()

def my_func(val,args,args1,args2):   //可以传多个参数

    return val+args+args1+args2


使用

{% load xx %}

{% my_func name "sss" "aaa" "bbb" %}  //拼接内容使用空格分开


html中可以引入别的组件

{% include "csrf1.html" %}


[11]. session使用

-cookie:

    保存在客户端浏览器上

-session:

    存储在服务器上

优势:安全,储存数据没有限制

session依赖cookie


服务端session接收处理:

    1.当用户名和密码正确,将用户名存储到服务端{"abc":{"username"}:'frank'}

    2.返回给客户端浏览器一个随机字符串,就是我们存储服务端abc,通过cookie来返回set_cookie('xxx':'abc')


举例session的使用

-s2day20-urls.py

urlpatterns = [
    url(r'^login/', views.login),
    url(r'^main/', views.main),
]

-app01-views.py

def login(request):
    if request.method=='GET':
        return render(request,'login.html')
    else:
        username=request.POST.get('username')
        password=request.POST.get('password')
        if username=='frank' and password=='123':
            request.session['username']='frank'
           
return redirect('/main/')
        else:
            return render(request,'login.html')

def main(request):
    res=request.session.get('username')
    if res:
        return render(request,'main.html',{"username":res})
    else:
        return render(request,'login.html')

-templates-login.html

<form action="/login/" method="post">
    {% csrf_token %}
    <input type="text" name="username">
    <input type="password" name="password" >
    <input type="submit" value="提交">
</form>

-templates-main.html

<h2>this is main,welcome,{{ username }}</h2>


访问地址:http://127.0.0.1:8005/login/


jango默认支持Session,并且默认是将Session数据存储在数据库中,即:django_session表中


settings.py

SESSION_ENGINE = 'django.contrib.sessions.backends.db'  # 引擎(默认)

SESSION_COOKIE_NAME = "sessionid"  # Sessioncookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
SESSION_COOKIE_PATH = "/"  # Sessioncookie保存的路径(默认)
SESSION_COOKIE_DOMAIN = None  # Sessioncookie保存的域名(默认)
SESSION_COOKIE_SECURE = False  # 是否Https传输cookie(默认)
SESSION_COOKIE_HTTPONLY = True  # 是否Sessioncookie只支持http传输(默认)
SESSION_COOKIE_AGE = 1209600  # Sessioncookie失效日期(2周)(默认)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False  # 是否关闭浏览器使得Session过期(默认)
SESSION_SAVE_EVERY_REQUEST = False  # 是否每次请求都保存Session,默认修改之后才保存(默认)



[12]. yaf的介绍:


MVC

models(存放数据库相关文件) views(存放html模板文件) controllers(处理和业务相关的文件)


MTV(django

models(存放数据库相关的文件) template(存放html模板文件) views(处理和业务相关的文件)



返回顶部