本文主要分成四个部分:
- django连接查询:一对一,一对多,多对多,自定义查询
- HttpRequest简介:request.GET与request.POST
- form模板:csrf跨站点攻击,处理表单
- cookie与session:设置与获取
- -
Django连接查询
一对一映射
--A表中的一条记录只能与B表中的一条记录匹配关联
--数据库中实现:
A表:设计主键
B表:有主键,增加一列,并引用A表中的主键值,还得增加一个唯一的约束
--语法:在models.py中设置
class Book(models.Model):
book=models.OneToOneField(Author,null=True,on_delete=CASCADE)
注意:
1.在djnago 2.0中on_delete选项为了避免两个表里的数据不一致问题;CASCADE此值设置,是级联删除
2.建立外键后,可以通过后台建立对应关系
#在views.py中查询
--正向查询 (通过book找author)
w=Book.objects.get(id=1)
a=w.author
--反向查询
(通过author找wife)
a=Author.objects.get(id=1)
w=a.book
注意:book是由Django通过OneToOneField在Author中默认增加的一个属性
一对多映射(1:M)
--什么是一对多
A表中的一条数据可以与B表中的任意多条数据匹配
--语法
属性=models.ForeignKey(实体类)
eg:
Book(M)和Publish(1)
class Book(models.Model):
publish=models.ForeignKey(Publisher)
--查询
1.正向查询-通过book查询publisher
book=Book.objects.get(id=1)
publisher=book.publisher
2.反向查询--通过Publisher查询Book
publisher=Publisher.objects.get(id=1)
通过publisher.book_set.all()得到所有的有关数据
bookSet = publisher.book_set.all()
多对多映射
--A表中的一条记录可以与B表中的任意多条记录匹配,同时B表中的记录也可以与A表中任意多条记录相匹配
--语法
class Author(models.Model):
publish=models.ManyToManyField(Publish)
--查询
1.正向查询:在Author中查询Publish
author=Author.objects.get(id=3)
pub_list=author.publish.all() #通过关联属性.all()
2.反向查询:在Publisher中查询Author
pub=Publisher.objects.get(id=1)
auList=pub.author_set.all()
自定义查询对象-objects(难点)
-声明类EntryManager,继承自models.Manager,并添加自定义函数
class EntryManager(models.Manager):
def 函数名(self,自定义参数):
return ...
-使用EntryManager覆盖Models中的objects
class Entry(models.Model):
objects=EntryManager()
eg:
#在models.py中
class BookManager(models.Manager):
def name_count(self,keywords):
return self.filter(title=keywords).count()
class Book(models.Model):
objects=BookManager()
title=models.CharField(max_length=40,verbose_name='书籍')
publication_data=models.CharField(default='2018-04-09',max_length=30,verbose_name='出版日期')
auth=models.ForeignKey(Author,null=True,on_delete=models.CASCADE,verbose_name='作者')
def __str__(self):
return self.title
class Meta:
db_table='book'
verbose_name_plural = '书籍'
#在views.py中
def name_counter_Views(request):
n=Book.objects.name_count('python')
return HttpResponse(n)
HttpRequet介绍
--HttpRequest请求对象,封装来请求过程中所有信息
--在Django中HttpRequest被化身成了request封装到视图处理函数中作为参数。该参数,在调用视图处理函数时自动传入
---dir(request)主要包括:
1、request.scheme : 请求协议
2、request.body 请求主体
3、request.path 请求路径
4、request.get_host() 请求的主机地址 / 域名
5、request.method 请求方法
6、request.GET get的请求数据
7、request.POST post的请求数据
8、request.COOKIES cookies的数据
9、request.META 请求的元数据
HTTP协议
--每个请求一个会有method(get,post,put,delete..)
-get 向服务器要数据时使用;传递数据到服务器时会直接将请求数据封装到地址之后
-post 该请求提交的数据全部封装在"请求主体"中
##只有post与put请求方式才能产生请求主体,其它请求方式没有请求主体
--获取请求提交的数据
--GET请求
request.GET['名称']
--POST请求
request.POST['名称']
form模板
csrf跨站请求伪造
--Cross Site Request Forgery
--某些恶意网站上包含链接、表单按钮或者JavaSricpt,它们会利用登录过的用户在浏览器中的认证信息试图在你的网站上完成某些操作,这就是跨站攻击
--解决跨站点发送post请求的解决方法
--删除CsrfViewMiddleWare中间件
--在视图函数增加@csrf_protect
--在模板中<form>下一行增加一个标签{%csrf_token%}
eg:
<form method='' action=''>
{%cstf_token%}
</form>
表单处理
-通过forms模块,允许将表单控件与py文件相结合
-使用forms模块
1.创建forms.py文件
2.导入 from django import forms
3.创建class,一个class对应一个表单(该class必须继承forms.Form)
4.在class中创建属性(一个属性对应一个表单控件)
表单字段查询:
https://docs.djangoproject.com/en/2.0/ref/forms/fields/
-在模版中,解析form对象
1.手动解析
{%for filed in form%}
<p>{{filed.label}}:{{field}}</p>
{%endfor%}
2.自动解析
{{form.as_p}}
{{form.as_ul}} #需要自定义ul
{form.as_table}#需要自定义table
注意:需要自定义<form>及提交按钮
eg:
#手动解析
<form action="http://localhost:8000/music/remark/" method="post">
{% csrf_token %}
{% for filed in form %}#}
<p>{{ filed.label }}:{{ field }}</p>#}
{% endfor %}#}
<p>
<input type="submit" value="提交">
</p>
</form>
#自动解析
<form action="http://localhost:8000/music/remark/" method="post">
{% csrf_token %}
{{ form.as_p }}
<p>
<input type="submit" value="提交">
</p>
</form>
在HTML中提交的表单内容给页可以传递给forms.Form
--在views.py中
def remark_views(request):
form=RemarkForm(request.POST)
if form.is_valid: #必须要经过验证才能继续
cd=form.cleaned_data #封装来提交的数据
print(cd['uname'])
forms的高级处理
-将Models和Forms结合到一起使用
-通过Models自动生成表单
1.创建class,EntryForm,并继承自forms.ModelForm
2.创建内部类Meta,并定义相关信息
--model:指定关联的Models是谁
--fields
-指定一个列表,声明允许生成表单控件的属性
-取值"__all__",表示全部属性都允许被生成表单控件
-labels-字典
{'属性1':'显示文本1'
}
# 声明一个ModelForm类,与Users实体相关联
class UsersForm(forms.ModelForm):
class Meta:
# 1.定义关联的Models
model = Users
# 2.定义要生成控件的字段
fields = '__all__' # ['uname','upwd']
# 3.为生成控件的字段指定标签
labels = {
'uname': '用户名称',
'upwd': '用户密码',
'uage': '用户年龄',
'uemail': '电子邮箱'
}
内置小部件wifgets
--生成到网友上的控件类型
eg:
class WidgetForm(forms.Form):
uname = forms.CharField(
label='用户名称',
widget=forms.TextInput(
attrs={
'class': 'form-control',
'placeholder': '请输入用户名'
}
)
)
upwd = forms.CharField(
label='用户密码',
widget=forms.PasswordInput(
attrs={
'class': 'form-control',
'placeholder': '请输入密码'
}
)
)
cookie和session
cookies
-cookies是一种数据存储技术;将一段文本保存在客户端(浏览器)的一种技术。并可以长时间的保存
-cookies的使用场合:保存登录信息;保存用户的搜索关键字
1.设置cookies(保存数据库到客户端)
#不使用模板
resp=HttpResponse('给客户端的一句话')
resp.set_cookie(key,value,expires)
return resp
key:cookie的名称
value:保存的cookie的值
expires:保存的时间,以s为单位
eg:
resp.set_cookie('uname','zsf',60*6)
#使用模板
resp=HttpResponseRedirect('/login/')
resp.set_cookie(key,value,expires)
return resp
#重定向
resp=HttpResponseRedirect('/login/')
resp.set_cookie(key,value,expires)
return resp
2.获取cookies(从客户端获取数据)
request.COOKIES
#设置cookie
def add_Views(request):
resp=HttpResponse('给客户端一句话')
resp.set_cookie('uname','xiaoming',60*30*10)
return resp
#获取cookie
def get_cookie_views(request):
print(request.COOKIES)
if 'uname' in request.COOKIES:
return HttpResponse(request.COOKIES['uname'])
return HttpResponse('获取cookies成功')
session-会话
--session就是每个服务器临时开辟的一段空间,用于保存相关的请求信息
--session的应用场合
session也是为了存放数据而存在的,通常会把服务器端要用到数据保存进session
--使用session
1.设置session的值
request.session['key']
request.session.set_expiry(time):设置过期时间,如果设置为0的话,则表示浏览器关闭失效
eg:
def add_session_views(request):
request.session['uname']='lihua'
request.session.set_expiry(10)
return HttpResponse('add session ok')
2.获取session的值
request.session.get('key')
eg:
def get_session_views(request):
if 'uname' in request.session:
uname=request.session.get('uname')
return HttpResponse('欢迎'+uname)
else:
return HttpResponse('对不起')
3.删除session的值
del request.session['key']
def log_out_views(request):
del request.session['uname']
return HttpResponseRedirect('/index/')
4.settings.py 有session的设置
-SESSION_COOKIE_AGE=60*30
-SESSION_EXPIRE_AT_BROWSER_CLOSE=True
def add_session_views(request):
request.session['uname']='lihua'
request.session.set_expiry(10)
return HttpResponse('add session ok')
def get_session_views(request):
if 'uname' in request.session:
uname=request.session.get('uname')
return HttpResponse('欢迎'+uname)
else:
return HttpResponse('对不起')