Day63(ORM补充(1对1、Django类型)分页、CSRF攻击)

1. 一对一表

1.1 创建

class UserInfo(models.Model):
    name = models.CharField(max_length=32, null=True)

class Salary(models.Model):
    money = models.CharField(max_length=32, null=True)
    su = models.OneToOneField('UserInfo', null=True)

1.2 查询

# 1、普通查询
res = models.UserInfo.objects.all()
print(res)
for row in res:
    print(row.id, row.name)

# 2、正向查询
res = models.Salary.objects.all()
for row in res:
    print(row.su.name, row.money)

# 3、反向查询
res = models.UserInfo.objects.all()
for row in res:
    print(row.name, row.salary.money)

2. Django类型

3、参数

- 参数:
    max_length=32
    null=True  : 可以设置为null
    db_index=True : 设置索引
    default : 设置默认值
    unique : 设置唯一索引
        
    db_column: 设置一个列名
    
    unique_together: 联合唯一索引
    index_together :普通联合索引
        class Meta:
            unique_together = (
                ('money', 'us_id'),
                ....
            )
            index_together = (
                ('money', '')
                ....
            )

4、Django-admin

djagno-admin:
    django自带的管理后台系统
        命令生成:
            python3 manage.py  createsuperuser
    想要管理自己生成的表:
        admin.py:
            from app01 import models
            admin.site.register(models.UserInfo)
        
    
        django-admin中的列类型:
            EmailField(CharField):
                - 字符串类型,Django Admin以及ModelForm中提供验证机制
            IPAddressField(Field)
                - 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制
            GenericIPAddressField(Field)
                - 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4和Ipv6
                - 参数:
                    protocol,用于指定Ipv4或Ipv6, 'both',"ipv4","ipv6"
                    unpack_ipv4, 如果指定为True,则输入::ffff:192.0.2.1时候,可解析为192.0.2.1,开启刺功能,需要protocol="both"
            URLField(CharField)
                - 字符串类型,Django Admin以及ModelForm中提供验证 URL
            SlugField(CharField)
                - 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号)
            CommaSeparatedIntegerField(CharField)
                - 字符串类型,格式必须为逗号分割的数字
            UUIDField(Field)
                - 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证
            FileField(Field)
    
        djagno-admin中的参数 :
            verbose_name        Admin中显示的字段名称        
    
            blank               Admin中是否允许用户输入为空
            editable            Admin中是否可以编辑
            help_text           Admin中该字段的提示信息

            choices             Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
            choices = (
                (1, ''),
                (2, '')
            )
            gender = models.IntegerField(choices=chocies)
            
            id name  gender (男女)

5、分页

class PageInfo():
    def __init__(self, cur_page, total, per_page=5, show_page=5):
        try:
            self.cur_page = int(cur_page)
        except Exception as e:
            self.cur_page = 1

        self.per_page = per_page
        self.show_page = show_page

        a, b = divmod(total, per_page)  # a为商, b为余数
        if b:
            self.total_page = a + 1
        else:
            self.total_page = a

    def get_start(self):
        return (self.cur_page - 1) * (self.per_page)


    def get_stop(self):
        return self.cur_page * self.per_page

    def page(self):
        half = int((self.show_page) / 2)

        # 总页数 < show_page
        if self.total_page < self.show_page:
            begin = 1
            stop = self.total_page
        else:  # 总页数 > show_page
            if self.cur_page - 1 < half:
                begin = 1
                stop = self.show_page + 1
            elif self.cur_page + half > self.total_page:
                begin = self.total_page - self.show_page + 1
                stop = self.total_page + 1
            else:
                begin = self.cur_page - half
                stop = self.cur_page + half + 1

        sli = []

        if self.cur_page == 1:
            s = "<li class='disabled'><a  href='#'>上一页</a></li>"
        else:
            s = "<li><a href='/app2/students/?cur_page=%s'>上一页</a></li>" % (self.cur_page - 1)

        sli.append(s)
        for num in range(begin, stop):
            if num == self.cur_page:
                s = "<li><a href='/app2/students/?cur_page=%s'>%s</a></li>" % (num, num)
            else:
                s = "<li><a href='/app2/students/?cur_page=%s'>%s</a></li>" % (num, num)
            sli.append(s)
        if self.cur_page == self.total_page:
            s = "<li class='disabled'><a href='#'>下一页</a></li>"
        else:

            s = "<li><a href='/app2/students/?cur_page=%s'>下一页</a></li>" % (self.cur_page + 1)
        sli.append(s)
        page_str = " ".join(sli)

        return page_str


def students(request):
    classes = Class.objects.all()

    cur_page = request.GET.get('cur_page')

    # 获得总行数, 进而获得页数
    total = Students.objects.count()

    pageinfo = PageInfo(cur_page, total)
    start = pageinfo.get_start()
    stop = pageinfo.get_stop()

    students = Students.objects.all()[start:stop]
    return render(request, 'students.html', {'students': students, 'classes': classes, 'pageinfo':pageinfo})

HTML核心代码

</li>
    {{ pageinfo.page | safe}}
<li>

6、网页攻击

Xss: 跨站脚本攻击

CSRF:跨站请求伪造

6.1 XSS攻击

网页攻击
Xss攻击
1、原理

  xss攻击为跨站脚本攻击,主要原因是用户输入的内容不可控形式为在别人的评论区,

  或者留言板写入js代码并且提交,如果我们不添加防护措施,就会造成,输入的

  js代码会被浏览器解析执行,从而让别人获取到我们浏览器中的信息

2、代码

  django中是默认有xss保护的,

  如果我们想要取消xss保护,通关 管道符 加上 safe

  前端接收参数  {{ page_info | safe }}

  后端直接传入js代码, 就可以被浏览器解析执行

6.2 CSRF攻击

6.2.1 开启全局的csrf验证

1. settings中,打开注释 'django.middleware.csrf.CsrfViewMiddleware',
2. 表单中,开启csrf_token

<form>
    {% csrf_token %}
    <input type='text'>
</form>

如上, 全站都会进行csrf验证

6.2.2 关闭部分的csrf验证:

1. settings中,打开注释 ====》'django.middleware.csrf.CsrfViewMiddleware',
2. views中,引入如下函数

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')

如上, 即便全局开启验证,但是可以使用装饰器进行特殊处理,不使用

6.2.3 开启部分的CSRF验证:

1. settings中,注释 ====》#'django.middleware.csrf.CsrfViewMiddleware',
2. views中,引入如下函数

from django.views.decorators.csrf import csrf_protect

@csrf_protect
def csrf1(request):
if request.method == 'GET':
return render(request, 'csrf1.html')
else:
return HttpResponse('ok')

如上, 即便全局关闭验证,但是可以使用装饰器进行特殊处理

6.2.4 CBV: 若是CBV:

from django.utils.decorators import method_decorator

@method_decorator(csrf_protect, name='get')
class User(View):
    def get(self, request):
        pass
    def post(self, request):
        pass    

ajax:

csrftoken = $('input[name="csrfmiddlewaretoken"]').val()

$.ajax({
    type:"POST",
    url : '/xxxx/',
    data: {"name":'xxxx'},
    headers : {'X-CSRFToken': token},
    success: function(){
        console.log(data)
    }
})

猜你喜欢

转载自www.cnblogs.com/gouyang/p/11221397.html