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