1什么时候用母版?2html页面有重复的代码,把它们提取出来放到一个单独的html文件(比如:导航条和左侧菜单)34子页面如何使用母版?5{%extends'base.html'%}-->必须要放在子页面的第一行6母版里面定义block(块),子页面使用block(块)去替换母版中同名的块
(2)组件
1什么时候用组件?2重复的代码,包装成一个独立的小html文件。34如何使用?5{%include'nav.html'%}
(3)Django模板语言中关于静态文件路径的灵活写法
(4)自定义simple_tag和自定义inclusion_tag
1自定义的simple_tag:2比filter高级一点点,返回一段文本3它可以接受的参数个数大于245自定义的inclusion_tag:6用来返回一段html代码(示例:返回ul标签)py文件(放在在app下面新建的templatetags文件夹(包)):
HTML:
(1)什么是FBV及CBV
视图:接收请求返回响应那部分
FBV:functionbaseview基于函数的视图
CBV:classbaseview基于类的视图
(2)CBV实例
views.py:
1#CBV实例-添加新的出版社2classAddPublisher(View):3defget(self,request):4returnredirect("/book/publisher_list/")56defpost(self,request):7new_name=request.POST.get("publisher_name",None)8ifnew_name:9#通过ORM去数据库里新建一条记录10models.Publisher.objects.create(name=new_name)11returnredirect("/book/publisher_list/")urls.py:
1url(r'^add_publisher/',views.AddPublisher.as_view()),
(3)上传文件
上传文件要使用到request的以下参数:
request.FILES:包含所有上传文件的类字典对象;FILES中的每一个Key都是
前端HTML:
1
1defupload(request):2ifrequest.method=="POST":3filename=request.FILES["upload-file"].name4#在项目目录下新建一个文件->项目根目录5withopen(filename,"wb")asf:6#从上传的文件对象中一点一点读7forchunkinrequest.FILES["upload-file"].chunks():8#写入本地文件9f.write(chunk)10returnHttpResponse("上传OK")11returnrender(request,"test/test_upload.html")
(1)djangoORM增删改查
(2)ORM字段
常用字段:
常用的字段参数:
DateField和DateTimeField才有的参数:
(3)关系字段
eg:
关于多对多:
1#多对多的方式:2#1.ORMManyToManyField()自动帮我创建第三张表-->关系表中没有额外字段、ORM封装了很多方法可以使用:add()remove()set()clear()34#2.自己创建第三张表,利用外键分别关联作者和书这种方法关联查询比较麻烦,因为没办法使用ORM提供的便利方法56#3.自己创建第三张表,用ORM的ManyToManyField()的through指定表名(自建的关系表)-->可向关系表中添加额外字段,使用此种方式没有ORM封装的方法可使用注:through_fields=(field1,field2)field1是关系表通过哪个属性可以找到这张表789#我们应该用哪种?看情况:10#如果你第三张表没有额外的字段,就用第一种11#如果你第三张表有额外的字段,就用第三种或第一种1213#有额外字段的实际情况:14"""15相亲网站:16Boy17girl=ManyToManyField(to=“Girl")1819Girl2021约会记录:多对多22idboy_idgirl_iddate23"""实例:
(4)单表查询的双下划线用法
1models.Book.objects.filter(id__gt=1)2models.Book.objects.filter(id__in=[1,2,3])3models.Book.objects.filter(id__range=[1,5])4models.Book.objects.filter(title__contains="python")5models.Book.objects.filter(title__icontains="python")6models.Book.objects.filter(title__startswith="python")7models.Book.objects.filter(title__endswith="python")8models.Book.objects.filter(publish_date__year=2017)9models.Book.objects.filter(publish_date__month=2)
(1)ORM查询
返回QuerySet对象:
返回一个特殊的QuerySet对象:
返回一个具体对象:
返回布尔值:
exists():如果QuerySet包含数据,就返回True,否则返回False
返回数字:
count():返回数据库中匹配查询(QuerySet)的对象数量
多对多查询拓展:
(2)外键的查询操作
1#正向查询:2#查询第一本书的出版社3book_obj=models.Book.objects.all().first()4ret=book_obj.publisher5res=book_obj.publisher.name6print(ret,res)7#查询id是7的书的出版社的名称8#利用双下划线跨表查询双下划线就表示跨了一张表9ret=models.Book.objects.filter(id=7).values_list("publisher__name")10print(ret)1112#反向查询:13#1.基于对象查询14publisher_obj=models.Publisher.objects.get(id=1)#得到一个具体的对象15#ret=publisher_obj.book_set.all()16#在外键字段中加上related_name="books",之后就要使用下面的方法查询:17ret=publisher_obj.books.all()18print(ret)19#2.基于双下划线20ret=models.Publisher.objects.filter(id=1).values_list("books__title")21print(ret)注意:
(3)多对多操作
查询:
1#查询第一个作者:2author_obj=models.Author.objects.first()3print(author_obj.name)4#查询写过的书:5ret=author_obj.book.all()6print(author_obj.book,type(author_obj.book))7print(ret)增删改查操作:
1#1.create2#通过作者创建一本书,会自动保存3#做了两件事:1.在book表里面创建一本新书,2.在作者和书的关系表中添加关联记录4author_obj=models.Author.objects.first()5author_obj.book.create(title="wyb自传",publisher_id=1)67#2.add8#在wyb关联的书里面,再加一本id是8的书9book_obj=models.Book.objects.get(id=8)10author_obj.book.add(book_obj)11#添加多个12book_objs=models.Book.objects.filter(id__gt=5)13author_obj.book.add(*book_objs)#要把列表打散再传进去14#直接添加id15author_obj.book.add(9)1617#3.remove18book_obj=models.Book.objects.get(title="跟Alex学泡妞")19author_obj.book.remove(book_obj)20#把id是8的记录删掉21author_obj.book.remove(8)2223#4.clear24#清空25jing_obj=models.Author.objects.get(id=2)26jing_obj.book.clear()注意:
对于ForeignKey对象,clear()和remove()方法仅在null=True时存在
(4)分组和聚合查询
聚合查询:
aggregate()是QuerySet的一个终止子句,意思是说,它返回一个包含一些键值对的字典。
键的名称是聚合值的标识符,值是计算出来的聚合值。键的名称是按照字段和聚合函数的名称自动生成出来的
用到的内置函数:
1fromdjango.db.modelsimportAvg,Sum,Max,Min,Count实例如下:
1fromdjango.db.modelsimportAvg,Sum,Max,Min,Count2res=models.Book.objects.all().aggregate(price_avg=Avg("price"),price_max=Max("price"),price_min=Min("price"))3print(res)4print(res.get("price_avg"),res.get("price_max"),res.get("price_min"))5print(type(res.get("price_max")))#
分组查询:
1#查询每一本书的作者个数2fromdjango.db.modelsimportAvg,Sum,Max,Min,Count3ret=models.Book.objects.all().annotate(author_num=Count("author"))4print(ret)5forbookinret:6print("书名:{},作者数量:{}".format(book.title,book.author_num))78#查询作者数量大于1的书9ret=models.Book.objects.all().annotate(author_num=Count("author")).filter(author_num__gt=1)10print(ret)1112#查询各个作者出的书的总价格13ret=models.Author.objects.all().annotate(price_sum=Sum("book__price"))14print(ret)15foriinret:16print(i,i.name,i.price_sum)17print(ret.values_list("id","name","price_sum"))
(5)F查询和Q查询
F查询:
在上面所有的例子中,我们构造的过滤器都只是将字段值与某个常量做比较。如果我们要对两个字段的值做比较,那该怎么做呢?
Django提供F()来做这样的比较。F()的实例可以在查询中引用字段,来比较同一个model实例中两个不同字段的值
F查询实例:
Q查询:
filter()等方法中的关键字参数查询都是一起进行“AND”的。如果你需要执行更复杂的查询(例如OR语句),你可以使用Q对象
Q查询实例:
1fromdjango.db.modelsimportQ2#查询卖出数大于1000,并且价格小于100的所有书3ret=models.Book.objects.filter(maichu__gt=1000,price__lt=100)4print(ret)56#查询卖出数大于1000,或者价格小于100的所有书7ret=models.Book.objects.filter(Q(maichu__gt=1000)|Q(price__lt=100))8print(ret)910#Q查询和字段查询同时存在时,字段查询要放在Q查询的后面11ret=models.Book.objects.filter(Q(maichu__gt=1000)|Q(price__lt=100),title__contains="金老板")12print(ret)
ORM拓展内容总结:
(1)什么是csrf
csrf:跨站请求伪造
百度解释:CSRF(Cross-siterequestforgery)跨站请求伪造,也被称为“OneClickAttack”或者SessionRiding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性
一句话解释:CSRG是指通过通过伪造页面来欺骗用户,让用户在钓鱼网址上输入关键信息,然后修改部分数据提交给真正的服务端程序
(2)csrf实例
钓鱼网站的页面和正经网站的页面对浏览器来说有什么区别?(页面是怎么来的?)
钓鱼网站如何实现钓鱼:前端页面一模一样,但是在表单中隐藏了某些关键的input然后这些input写成无用的input显示在页面上,这些隐藏的input的value是固定值,无论你在那些无用的input上输入什么值,最后提交给服务端的值都是确定的
详情见下面实例:
真正的网站前端代码:
123 13转出:14 17转入:18 21金额:22 25真正的网站
11