Django第三天
Django深入查询
#model.py from django.db import models # Create your models here. #书表 class Book(models.Model): title = models.CharField(max_length=32) price = models.DecimalField(max_digits=6,decimal_places=2) create_time = models.DateField() memo = models.CharField(max_length=32,default="") publish = models.ForeignKey(to="Publish",default=1) author = models.ManyToManyField("Author") def __str__(self): return self.title #出版社表 class Publish(models.Model): name = models.CharField(max_length=32) email = models.CharField(max_length=32) #作者表 class Author(models.Model): name = models.CharField(max_length=32) def __str__(self): return self.name #作者信息表 class AuthorDetail(models.Model): tel=models.CharField(max_length=32) email=models.EmailField() author=models.OneToOneField("Author") def __str__(self): return self.email
基于对象的查询(子查询)
1.首先我们要明白什么是正向查询和反向查询?
所谓正向查询就是:关联字段所在的表到被关联的表查询称为正向查询;反向查询:就是被关联表到关联字段表方向的查询。
例如:表关系一对多(出版社==>书)
因为关联字段建立在多的一方、所以此时出版社到书的方向查询称为反向查询、书到出版社方向的查询称为正向查询。
2.什么是子查询?
子查询就是将上一次的查询结果作为下一次查询的条件。
3.为什么要拆表?
原因大致有3点:
1.业务信息量太大
2.单表能描述的信息太少
3.单表会涉及很多重复性的数据
我们就以博客系统中的图书表、作者表、出版社表为例。
一对多关系的查询
#1.查询id=8的书籍的出版社的名称(书==>出版社,正向查询,按照字段直接查询) book = Book.objects.filter(id='9').first() #first查到的是具体的对象。 print(book.publish.name) #注意此时设计关联字段、所以不能直接查询publish_id,而是要查到这个出版对象,然后根据对象查到名字,得到的结果只有一个,因为一本书只有一个出版社。 sql: SELECT "app01_book"."id", "app01_book"."title", "app01_book"."price", "app01_book"."create_time", "app01_book"."memo", "app01_book"."publish_id" FROM "app01_book" WHERE "app01_book"."id" = 9 ORDER BY "app01_book"."id" ASC LIMIT 1; args=(9,) SELECT "app01_publish"."id", "app01_publish"."name", "app01_publish"."email" FROM "app01_publish" WHERE "app01_publish"."id" = 2; args=(2,) #2.查询工业出版社出版过的书籍名称(出版社==>书,反向查询,按表明小写_set:book_set) publish = Publish.objects.filter(name='工业出版社').first() #查询到出版社对象 for item in publish.book_set.all(): #然后根据出版社.book_set固定格式查出所出版的书对象 print(item) #打印的是每一本书对象,会有多个值,因为一个出版社可以出版多本书。 sql: SELECT "app01_publish"."id", "app01_publish"."name", "app01_publish"."email" FROM "app01_publish" WHERE "app01_publish"."name" = '工业出版社' ORDER BY "app01_publish"."id" ASC LIMIT 1; args=('工业出版社',) SELECT "app01_book"."id", "app01_book"."title", "app01_book"."price", "app01_book"."create_time", "app01_book"."memo", "app01_book"."publish_id" FROM "app01_book" WHERE "app01_book"."publish_id" = 2 LIMIT 21; args=(2,)
多对多的表关系查询
#1.查询书名为红楼梦的所有作者的名字(书==>作者,正向查询,按照字段查询) book = Book.objects.filter(title='红楼梦').first() #查到图书对象 print(book.author.all()) #多对多关系设计关联字段,所以不能直接查询author_id,而是查作者对象,因为一本书有多个作者所以需要查出所有。他的结果可能是多个或者一个。 sql: SELECT "app01_book"."id", "app01_book"."title", "app01_book"."price", "app01_book"."create_time", "app01_book"."memo", "app01_book"."publish_id" FROM "app01_book" WHERE "app01_book"."title" = '红楼梦' ORDER BY "app01_book"."id" ASC LIMIT 1; args=('红楼梦',) SELECT "app01_author"."id", "app01_author"."name" FROM "app01_author" INNER JOIN "app01_book_author" ON ("app01_author"."id" = "app01_book_author"."author_id") WHERE "app01_book_author"."book_id" = 10 LIMIT 21; args=(10,) #2.查询出吴承恩出版的书籍名称(作者==>图书,反向查询,按表明_set:book_set) author = Author.objects.filter(name='吴承恩').first() #查出作者对象 for n in author.book_set.all(): #根据作者对象.book_set固定格式查询出所有的书对象 print(n.name) #遍历queryset打印每一本书对象 #方法2 author = Author.objects.filter(name='吴承恩').first() res=author.book_set.all().values("title") #直接取出每本书的名称 for n in res: print(n) #遍历打印,结果为出了多少本书,就有多少结果,打印的是{'title': '红楼梦'}格式的字典
一对一关系表的查询
#1.查询罗贯中的手机号码(作者==>作者信息,反向查询,因为关联字段创建在作者信息表中,按照小写表明查询) auth = Author.objects.filter(name='罗贯中').first() #查出作者对象 print(auth.authordetail.tel) #根据作者对象然后.authordetail查出作者的所有信息,最后查出手机号码 sql: SELECT "app01_author"."id", "app01_author"."name" FROM "app01_author" WHERE "app01_author"."name" = '罗贯中' ORDER BY "app01_author"."id" ASC LIMIT 1; args=('罗贯中',) SELECT "app01_authordetail"."id", "app01_authordetail"."tel", "app01_authordetail"."email", "app01_authordetail"."author_id" FROM "app01_authordetail" WHERE "app01_authordetail"."author_id" = 3; args=(3,) #2.查出手机号为223的作者名称(信息==>作者,正向查询,直接按照字段查询) auth_info = AuthorDetail.objects.filter(tel='223').first() #首先查出该手机号对象 print(auth_info.author.name) #然后根据手机号对象.author(作者对象).name 查询作者的name sql: SELECT "app01_authordetail"."id", "app01_authordetail"."tel", "app01_authordetail"."email", "app01_authordetail"."author_id" FROM "app01_authordetail" WHERE "app01_authordetail"."tel" = '223' ORDER BY "app01_authordetail"."id" ASC LIMIT 1; args=('223',) SELECT "app01_author"."id", "app01_author"."name" FROM "app01_author" WHERE "app01_author"."id" = 4; args=(4,) #一对一的查询结果只有一个
基于queryset的查询
我们就以博客系统中的图书表、作者表、出版社表为例。
一对多关系的查询
#1.查询价格等于111元的书籍的版社名称(书籍==>出版社,正向查询,按照字段) book = Book.objects.filter(price='111') #首先根据价格查出所有的符合的对象,可能有多个。 for n in book: print(n.title,n.publish.name) #遍历根据对象查询取出相关字段 #方法2 book = Book.objects.filter(price='111').values("title","publish__name") #根据价格符合的对象直接取value,但是明确分辨什么的是什么的?,publish__name就是取的publish表中的name字段,title是book表自己的tiele for item in book: print(item) #最后的格式为queryset {'title':xxx,'publish__name:xxx'},结果可能有多个值 sql: SELECT "app01_book"."title", "app01_publish"."name" FROM "app01_book" INNER JOIN "app01_publish" ON ("app01_book"."publish_id" = "app01_publish"."id") WHERE "app01_book"."price" = '111'; args=(Decimal('111'),) 介绍下values的原理: for book in Book.objects.filter(price=100): temp.append({ "title":book.title, "publish__name":book.publish.name, }) #2.查询工业出版社出版过的书籍名称(出版社==>书,反向查询,按表名小写) publist = Publish.objects.filter(name='工业出版社').values("book__title") #首先查找出工业出版社对象,然后取value,book__name==>书籍的名称,这是queryset查询的语法 for n in publist: #结果为queryset,有多个值 print(n) #字典格式{'book__title': 'python'} sql: SELECT "app01_book"."title" FROM "app01_publish" LEFT OUTER JOIN "app01_book" ON ("app01_publish"."id" = "app01_book"."publish_id") WHERE "app01_publish"."name" = '工业出版社'; args=('工业出版社',)
多对多关系表查询
#1.查询出吴承恩出版的书籍名称(作者==>书,反向查询,按表名小写) author = Author.objects.filter(name='吴承恩').values("book__title") #根据作者查询书籍名称 print(author) #得到的是queryset对象 sql: SELECT "app01_book"."title" FROM "app01_author" LEFT OUTER JOIN "app01_book_author" ON ("app01_author"."id" = "app01_book_author"."author_id") LEFT OUTER JOIN "app01_book" ON ("app01_book_author"."book_id" = "app01_book"."id") WHERE "app01_author"."name" = '吴承恩' LIMIT 21; args=('吴承恩',) #2.查询Go的所有作者(书==>作者,正向查询,按照字段) book = Book.objects.filter(title='GO').values("author__name") print(book) #返回queryset对象,返回的值是每本书绑定的作者的和 sql: SELECT "app01_author"."name" FROM "app01_book" LEFT OUTER JOIN "app01_book_author" ON ("app01_book"."id" = "app01_book_author"."book_id") LEFT OUTER JOIN "app01_author" ON ("app01_book_author"."author_id" = "app01_author"."id") WHERE "app01_book"."title" = 'GO' LIMIT 21; args=('GO',)
一对一关系变查询
#1.查找手机号为223的作者名字(信息==>作者,正向查询,直接按字段) info = AuthorDetail.objects.filter(tel='223').values("author__name") print(info) #查询的结果是唯一一个 sql: SELECT "app01_author"."name" FROM "app01_authordetail" INNER JOIN "app01_author" ON ("app01_authordetail"."author_id" = "app01_author"."id") WHERE "app01_authordetail"."tel" = '223' LIMIT 21; args=('223',) #2.查询曹雪晴的手机号码(作者==>信息,反向查询,表明小写) author = Author.objects.filter(name='曹雪晴').values("authordetail__tel") print(author) #查询结果为唯一值 #3.查询手机号码以1结尾的作者名字 author = AuthorDetail.objects.filter(tel__endswith='1').values("author__name") #tel__endswith表示结尾 print(author) #返回唯一的对象
基于聚合和分组的查询
我们就以博客系统中的图书表、作者表、出版社表为例。
在使用聚合时需要导入模块
from django.db.models import Avg,Count,Max,Min
#1.统计所有书籍的平均价格 res = Book.objects.all().aggregate(price=Avg("price")) #使用aggregate函数,计算聚合 print(res) #返回的结果为字典,{'price': 115.0} sql: SELECT AVG("app01_book"."price") AS "price" FROM "app01_book"; args=() #2.查询每个出版社出版的书的个数 count = Publish.objects.all().annotate(count=Count("book")).values("name","count") #annotate表示分组 print(count) #得到的结果为queryset对象,[{'name': '人民出版社', 'count': 1}, {'name': '工业出版社', 'count': 2}],结果为多少个出版社就有多少个结果. sql: SELECT "app01_publish"."name", COUNT("app01_book"."id") AS "count" FROM "app01_publish" LEFT OUTER JOIN "app01_book" ON ("app01_publish"."id" = "app01_book"."publish_id") GROUP BY "app01_publish"."id", "app01_publish"."name", "app01_publish"."email" LIMIT 21; args=() #3.查询每一个作者出版的书籍的平均价格 res = Author.objects.all().annotate(price=Avg("book__price")).values("name","price") #这里首先要搞明白是每一个作者出的书,不是出版社出的书, print(res) #返回个数为作者的个数,[{'name': '曹雪晴', 'price': 111.0}, {'name': '吴承恩', 'price': 117.0}, {'name': '罗贯中', 'price': None}, {'name': '施耐奄', 'price': 111.0}] sql: SELECT "app01_author"."name", AVG("app01_book"."price") AS "price" FROM "app01_author" LEFT OUTER JOIN "app01_book_author" ON ("app01_author"."id" = "app01_book_author"."author_id") LEFT OUTER JOIN "app01_book" ON ("app01_book_author"."book_id" = "app01_book"."id") GROUP BY "app01_author"."id", "app01_author"."name" LIMIT 21; args=() #4.查询每一本书籍名称以及作者的个数 res = Book.objects.all().annotate(count=Count("author")).values("title","count") print(res) #返回queryset对象 sql: SELECT "app01_book"."title", COUNT("app01_book_author"."author_id") AS "count" FROM "app01_book" LEFT OUTER JOIN "app01_book_author" ON ("app01_book"."id" = "app01_book_author"."book_id") GROUP BY "app01_book"."id", "app01_book"."title", "app01_book"."price", "app01_book"."create_time", "app01_book"."memo", "app01_book"."publish_id" LIMIT 21; args=() #5.查询价格大于200的每一本书籍名称以及作者的个数 res = Book.objects.filter(price__gt='200').annotate(count=Count("author")).values("title","count") #首先查出价格大于200的书籍 print(res) #返回queryset对象 sql: SELECT "app01_book"."title", COUNT("app01_book_author"."author_id") AS "count" FROM "app01_book" LEFT OUTER JOIN "app01_book_author" ON ("app01_book"."id" = "app01_book_author"."book_id") WHERE "app01_book"."price" > CAST('200' AS NUMERIC) GROUP BY "app01_book"."id", "app01_book"."title", "app01_book"."price", "app01_book"."create_time", "app01_book"."memo", "app01_book"."publish_id" LIMIT 21; args=(Decimal('200'),)
基于F与Q的查询
在使用F和Q查询前需要导入:from django.db.models import F,Q
#1.对ID为1的书的价格增加100元 res = Book.objects.filter(id='1').update(price=F("price")+100) print(res) #2.查询所有书籍中,评论数大于点赞数的书 ret=Book.objects.filter(comment_num__gt=F("poll_num")) print(ret) #3.查询所有书籍评论数大于阅读数的书 ret=Book.objects.filter(comment_num__gt=F("read_num")*10) print(ret) #Q #1.查询书名结尾是O、而且价格大于100的书 res = Book.objects.filter(title__endswith='O',price__gt=100) print(res) #返回queryset对象 sql: SELECT "app01_book"."id", "app01_book"."title", "app01_book"."price", "app01_book"."create_time", "app01_book"."memo", "app01_book"."publish_id" FROM "app01_book" WHERE ("app01_book"."title" LIKE '%O' ESCAPE '\' AND "app01_book"."price" > CAST('100' AS NUMERIC)) LIMIT 21; args=('%O', Decimal('100')) #2.查询书名以O结尾,或者价格不大于200元 res = Book.objects.filter(Q(title__endswith='O')|~Q(price__gt=200)) print(res) #返回queryset对象 sql: SELECT "app01_book"."id", "app01_book"."title", "app01_book"."price", "app01_book"."create_time", "app01_book"."memo", "app01_book"."publish_id" FROM "app01_book" WHERE ("app01_book"."title" LIKE '%O' ESCAPE '\' OR NOT ("app01_book"."price" > CAST('200' AS NUMERIC))) LIMIT 21; args=('%O', Decimal('200')) #3.查询书以O结尾,或者价价格小于200且不是2014年创建的书籍 res = Book.objects.filter(Q(title__endswith='O')|~Q(price__gt=200,create_time__year=2014)) print(res) #返回queryset对象
注意:Q只能写在,(点)的前面,写在后面会报错
#正确的写法 res = Book.objects.filter(Q(price__gt=100),title__endswith='O') print(res) #错误的写法 res = Book.objects.filter(title__endswith='O',Q(price__gt=100)) print(res)
Django之Ajax
首先我们要知道什么是Json?
JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式。
它基于 ECMAScript (w3c制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。
简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
Ajax简介
AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML)。
同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;
异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。
AJAX除了异步的特点外,还有一个就是:浏览器页面局部刷新;(这一特点给用户的感受是在不知不觉中完成请求和响应过程)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>compute</title> <script src="/static/jquery-3.3.1.min.js"></script> <!--请使用网络地址--> </head> <body> {% csrf_token %} <p><input id="n1" type="text">+<input id="n2" type="text">=<input id="res" type="text" value=""></p> <p><button id="button" value="提交">提交</button></p> <script> $("#button").click(function () { $.ajax({ url:"/app01/ajax/", type:"post", data:{ 'csrfmiddlewaretoken':$("[name='csrfmiddlewaretoken']").val(), n1:$("#n1").val(), n2:$("#n2").val() }, success:function (data) { var date = JSON.parse(data); $("#res").val(date.msg) } }) }) </script> </body> </html> #ajax的工作过程 1.整个过程中页面没有刷新,只是刷新页面中的局部位置而已! 2.当请求发出后,浏览器还可以进行其他操作,无需等待服务器的响应!
ajax的优点
1.AJAX使用Javascript技术向服务器发送异步请求; 2.AJAX无须刷新整个页面; 3.因为服务器响应内容不再是整个页面,而是页面中的局部,所以AJAX性能高;
ajax的参数
#1.请求参数 数据部分: data: 当前ajax请求要携带的数据,是一个json的object对象,ajax方法就会默认地把它编码成某种格式 (urlencoded:?a=1&b=2)发送给服务端;此外,ajax默认以get方式发送请求。 function testData() { $.ajax("/test",{ //此时的data是一个json形式的对象 data:{ a:1, b:2} }); processData: processData:声明当前的data数据是否进行转码或预处理,默认为true,即预处理;if为false, 那么对data:{a:1,b:2}会调用json对象的toString()方法,即{a:1,b:2}.toString() ,最后得到一个[object,Object]形式的结果。 contentType: contentType:默认值: "application/x-www-form-urlencoded"。发送信息至服务器时内容编码类型。用来指明当前请求的数据编码格式;urlencoded:?a=1&b=2;如果想以其他方式提交数据,比如contentType:"application/json",即向服务器发送一个json字符串: $.ajax("/ajax_get",{ data:JSON.stringify({ a:22, b:33}), contentType:"application/json", type:"POST", }); //{a: 22, b: 33} 注意:contentType:"application/json"一旦设定,data必须是json字符串,不能是json对象 后台views.py: json.loads(request.body.decode("utf8")) traditional: traditional:一般是我们的data数据有数组时会用到 :data:{a:22,b:33,c:["x","y"]}, traditional为false会对数据进行深层次迭代 。 #2.响应参数 dataType: 预期服务器返回的数据类型,服务器端返回的数据会根据这个值解析后,传递给回调函数。 默认不需要显性指定这个属性,ajax会根据服务器返回的content Type来进行转换;比如我们的服务器响应的content Type为json格式,这时ajax方法就会对响应的内容进行一个json格式的转换,if转换成功,我们在success的回调函数里就会得到一个json格式的对象;转换失败就会触发error这个回调函数。如果我们明确地指定目标类型,就可以使用data Type。dataType的可用值:html|xml|json|text|script 见下dataType实例.
csrf跨域的问题
#解决方法1 $.ajaxSetup({ data: {csrfmiddlewaretoken: '{{ csrf_token }}' }, }); #解决方法2 <form> {% csrf_token %} </form><br><br><br>$.ajax( data:{ "csrfmiddlewaretoken":$("[name='csrfmiddlewaretoken']").val() } #解决方法3 <script src="{% static 'js/jquery.cookie.js' %}"></script> $.ajax({ headers:{"X-CSRFToken":$.cookie('csrftoken')}, })
例子:当我们注册用户的时候、我们输入完成鼠标离开输入框之后,ajax会发起请求,校验用户是否存在。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>compute</title> <script src="/static/jquery-3.3.1.min.js"></script> </head> <body> {% csrf_token %} <p>user:<input id="user" type="text"><span id="sp"></span></p> <p>passwd:<input id="passwd" type="text"></p> <p> <button id="button" value="提交">提交</button> </p> <script> $("#user").blur(function () { $.ajax({ url: "/app01/ajax/", type: "post", data: { 'csrfmiddlewaretoken': $("[name='csrfmiddlewaretoken']").val(), user: $("#user").val(), passwd: $("#passwd").val() }, success: function (data) { var date = JSON.parse(data); if (date.status === 404) { $("#sp").html(date.msg).css("color", "red"); } } }) }); $("#button").click(function () { $.ajax({ url: "/app01/ajax/", type: "post", data: { 'csrfmiddlewaretoken': $("[name='csrfmiddlewaretoken']").val(), user: $("#user").val(), passwd: $("#passwd").val() }, success: function (data) { var date = JSON.parse(data); if (date.status === 200) { alert(date.msg) }else { $("#sp").html(date.msg).css("color", "red"); } } }) }) </script> </body> </html> #后端:view.py def ajax(request): if request.method == 'POST': user = request.POST.get('user') passwd = request.POST.get('passwd') if Author.objects.filter(name=user): msg = {"status": 404, "msg": "用户已存在"} else: if passwd == '123': msg = {"status": 200, "msg": "登陆成功"} else: msg = {"status": 500, "msg": "密码错误"} return HttpResponse(json.dumps(msg)) return render(request,'compute.html')
浏览器的cookie
概念
http协议的特点:
- 基于请求响应
- 短连接
- 无状态保存
cookie不属于http协议范围,由于http协议无法保持状态,但实际情况,我们却又需要“保持状态”,因此cookie就是在这样一个场景下诞生。
cookie的工作原理是:由服务器产生内容,浏览器收到请求后保存在本地;当浏览器再次访问时,浏览器会自动带上cookie,这样服务器就能通过cookie的内容来判断这个是“谁”了。
cookie虽然在一定程度上解决了“保持状态”的需求,但是由于cookie本身最大支持4096字节,以及cookie本身保存在客户端,可能被拦截或窃取,因此就需要有一种新的东西,它能支持更多的字节,并且他保存在服务器,有较高的安全性。这就是session,后面我们会讲述session技术。
由于http协议是无状态的,所以服务器根本不知道访问者是谁,那么上述的cookie就起到了桥接作用,我们为每个客户端分配一个不同的cookie-id,在服务器上保存一端时间,如用户的账号密码信息等。
cookie弥补了http无状态的不足,让服务器知道来的人是“谁”;但是cookie以文本的形式保存在本地,自身安全性较差;所以我们就通过cookie识别不同的用户,对应的在session里保存私密的信息以及超过4096字节的文本。
基于Django实现的cookie
#1.获取cookie request.COOKIES['key'] request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None) #参数: default: 默认值 salt: 加密盐 max_age: 后台控制过期时间 #2.设置cookie rep = HttpResponse(...) 或 rep = render(request, ...) 或 rep = redirect() rep.set_cookie(key,value,...) rep.set_signed_cookie(key,value,salt='加密盐',...)
cookie的参数
def set_cookie(self, key, 键 value='', 值 max_age=None, 超长时间 expires=None, 超长时间 path='/', Cookie生效的路径, 浏览器只会把cookie回传给带有该路径的页面,这样可以避免将 cookie传给站点中的其他的应用。 / 表示根路径,特殊的:根路径的cookie可以被任何url的页面访问 domain=None, Cookie生效的域名 你可用这个参数来构造一个跨站cookie。 如, domain=".example.com" 所构造的cookie对下面这些站点都是可读的: www.example.com 、 www2.example.com 和an.other.sub.domain.example.com 。 如果该参数设置为 None ,cookie只能由设置它的站点读取。 secure=False, 如果设置为 True ,浏览器将通过HTTPS来回传cookie。 httponly=False 只能http协议传输,无法被JavaScript获取 (不是绝对,底层抓包可以获取到也可以被覆盖) ): pass
由于cookie保存在客户端,所以使用js也可以操控cookie
<script src='/static/js/jquery.cookie.js'> </script> $.cookie("key", value,{ path: '/' });
删除cookie
response.delete_cookie("cookie_key",path="/",domain=name) cookie存储到客户端 优点: 数据存在在客户端,减轻服务器端的压力,提高网站的性能。 缺点: 安全性不高:在客户端机很容易被查看或破解用户会话信息
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>compute</title> <script src="/static/jquery-3.3.1.min.js"></script> </head> <body> {% csrf_token %} <p>user:<input id="user" type="text"><span id="sp"></span></p> <p>passwd:<input id="passwd" type="text"></p> <p> <button id="button" value="提交">提交</button> </p> <script> $("#user").blur(function () { $.ajax({ url: "/app01/ajax/", type: "post", data: { 'csrfmiddlewaretoken': $("[name='csrfmiddlewaretoken']").val(), user: $("#user").val(), passwd: $("#passwd").val() }, success: function (data) { var date = JSON.parse(data); if (date.status === 404) { $("#sp").html(date.msg).css("color", "red"); } } }) }); $("#button").click(function () { $.ajax({ url: "/app01/ajax/", type: "post", data: { 'csrfmiddlewaretoken': $("[name='csrfmiddlewaretoken']").val(), user: $("#user").val(), passwd: $("#passwd").val() }, success: function (data) { var date = JSON.parse(data); if (date.status === 200) { alert(date.msg) }else { $("#sp").html(date.msg).css("color", "red"); } } }) }) </script> </body> </html> #views.py def ajax(request): if request.method == 'POST': user = request.POST.get('user') passwd = request.POST.get('passwd') if Author.objects.filter(name=user).first(): msg = {"status": 404, "msg": "用户已存在"} res = HttpResponse(json.dumps(msg)) else: if passwd == '123': msg = {"status": 200, "msg": "登陆成功"} res = HttpResponse(json.dumps(msg)) res.set_cookie("login",hash(user)) #对登陆成功的用户设置cookie else: msg = {"status": 500, "msg": "密码错误"} res = HttpResponse(json.dumps(msg)) return res return render(request,'compute.html') #查看所有的图书 def books(request): res = request.COOKIES #如果获取不到cookie则302到登录页,只有带了cookie才让访问 if res: #获取数据图书对象 book_obj = Book.objects.all() if request.method == 'GET': return render(request,'books.html',locals()) else: return HttpResponse("{'code':'500','msg':'error'}") else: return redirect('/app01/ajax/')

浙公网安备 33010602011771号