一、cbv

  1. cbv(class-base-view) 基于类的视图
  2. fbv(func-base-view) 基于函数的视图

a.基本演示

  1. urlpatterns = [
  2.  
  3. url(r'^login.html$', views.Login.as_view()),
  4. ]

urls.py

  1. from django.views import View
  2.  
  3. class Login(View):
  4. """
  5. get 查
  6. post 创建
  7. put 更新
  8. delete 删除
  9. """
  10. def dispatch(self, request, *args, **kwargs):
  11. print('before')
  12. obj = super(Login,self).dispatch(request,*args,**kwargs)
  13. print("after")
  14. return obj
  15.  
  16. def get(self,request):
  17. return render(request,"login.html")
  18.  
  19. def post(self,request):
  20. print(request.POST)
  21.  
  22. return HttpResponse("Login.post")
  23.  
  24. view.py

views.py

二、分页

a.Django分页

  1. #浏览器访问
  2. http://127.0.0.1:8000/index.html/?page=9
  1. urlpatterns = [
  2.  
  3. #django分页
  4. url(r'^index', views.index),
  5. ]

urls

  1. #django 分页
  2. from django.core.paginator import Paginator,Page,PageNotAnInteger,EmptyPage
  3. def index(request):
  4. current_page = request.GET.get("page")
  5. user_list = models.User_info.objects.all()
  6. paginator = Paginator(user_list,10) #每页显示10条
  7.  
  8. """
  9. # count: 数据总个数
  10. # num_pages:总页数
  11. # page_range:总页数的索引范围,如: (1,10),(1,200)
  12. # page: page对象
  13. """
  14. try:
  15. posts = paginator.page(current_page) #当前页
  16. except PageNotAnInteger as e: #http://127.0.0.1:8000/index.html/?page=qqq 处理这种异常
  17. posts = paginator.page(1)
  18. except EmptyPage as e: #http://127.0.0.1:8000/index.html/?page=-10 捕获这种异常
  19. posts = paginator.page(1)
  20.  
  21. """
  22. # has_next 是否有下一页
  23. # next_page_number 下一页页码
  24. # has_previous 是否有上一页
  25. # previous_page_number 上一页页码
  26. # object_list 分页之后的数据列表
  27. # number 当前页
  28. # paginator paginator对象
  29. """
  30.  
  31. return render(request,"index.html",{"posts":posts})
  32.  
  33. views.py

views.py

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <h1>用户列表</h1>
  9. <ul>
  10. {% for row in posts.object_list %}
  11. <li>{{ row.name }}</li>
  12. {% endfor %}
  13. </ul>
  14. <div>
  15. {% if posts.has_previous %}
  16. <a href="/index.html/?page={{ posts.previous_page_number }}">上一页</a>
  17. {% endif %}
  18.  
  19. {% for num in posts.paginator.page_range %}
  20. <a href="/index.html/?page={{ num }}">{{ num }}</a>
  21. {% endfor %}
  22.  
  23. {% if posts.has_next %}
  24. <a href="/index.html/?page={{ posts.next_page_number }}">下一页</a>
  25. {% endif %}
  26. </div>
  27.  
  28. </body>
  29. </html>
  30.  
  31. index.html

index.html

b.自定义分页

  1. #浏览器访问
  2. http://127.0.0.1:8000/custom/?page=6
  1. urlpatterns = [
  2.  
  3. #自定义分页
  4. url(r'^custom/', views.custom),
  5. ]

urls

  1. from utils.pager import PageInfo
  2. #自定义分页
  3. def custom(request):
  4.  
  5. #总页数
  6. all_count = models.User_info.objects.all().count()
  7.  
  8. #用户当前想要访问的页码
  9. current_page = request.GET.get("page")
  10. page_info = PageInfo(current_page,all_count,10,"/custom",11)
  11.  
  12. user_list = models.User_info.objects.all()[page_info.start():page_info.end()]
  13.  
  14. return render(request,"custom.html",{"user_list":user_list,"page_info":page_info})
  15.  
  16. views.py

views.py

  1. class PageInfo(object):
  2.  
  3. def __init__(self,current_page,all_count,per_page,base_url,show_page=11):
  4.  
  5. #如果传值错误进入第一页
  6. try:
  7. self.current_page = int(current_page)
  8. except Exception as e:
  9. self.current_page = 1
  10. self.per_page = per_page #每页显示的个数
  11.  
  12. a,b = divmod(all_count,per_page) #页数 余数
  13. if b:
  14. a = a + 1
  15. self.all_page = a #总页码
  16. self.show_page = show_page
  17. self.base_url = base_url
  18.  
  19. def start(self):
  20. # 1 0: 10
  21. # 2 10:20
  22. # 3 20:30
  23. return (self.current_page-1) * self.per_page
  24.  
  25. def end(self):
  26. return self.current_page * self.per_page
  27.  
  28. def pager(self):
  29.  
  30. page_list = []
  31.  
  32. half = int((self.show_page-1)/2)
  33.  
  34. if self.all_page < self.show_page:
  35. begin = 1
  36. stop = self.all_page + 1
  37. else:
  38. if self.current_page < half:
  39. begin = 1
  40. stop = self.show_page + 1
  41. else:
  42. if self.current_page + half > self.all_page:
  43. begin = self.all_page - 10 +1
  44. stop = self.all_page + 1
  45. else:
  46. begin = self.current_page - half
  47. stop = self.current_page + half +1
  48.  
  49. if self.current_page <=1:
  50. prev = "<li><a href='#'>上一页</a></li>"
  51. else:
  52. prev = "<li><a href='%s/?page=%s'>上一页</a></li>"%(self.base_url,self.current_page - 1)
  53.  
  54. page_list.append(prev)
  55.  
  56. for i in range(begin,stop):
  57. if i == self.current_page:
  58. temp = "<li class='active'><a href='/custom/?page=%s'>%s</a></li>"%(i,i)
  59. else:
  60. temp = "<li><a href='%s/?page=%s'>%s</a></li>"%(self.base_url,i,i)
  61. page_list.append(temp)
  62.  
  63. if self.current_page >= self.all_page:
  64. nex = "<li><a href='#'>下一页</a></li>"
  65. else:
  66. nex = "<li><a href='%s/?page=%s'>下一页</a></li>" % (self.base_url,self.current_page + 1)
  67.  
  68. page_list.append(nex)
  69.  
  70. return "".join(page_list)
  71.  
  72. utils/pager.py

utils/pager.py

  1. from django.db import models
  2.  
  3. # Create your models here.
  4.  
  5. class User_type(models.Model):
  6. uid = models.BigAutoField(primary_key=True)
  7. title = models.CharField(max_length=32)
  8.  
  9. class User_info(models.Model):
  10. name = models.CharField(max_length=32)
  11. age = models.CharField(max_length=32)
  12. ut = models.ForeignKey("User_type")
  13.  
  14. models.py

models.py

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css" />
  7. </head>
  8. <body>
  9.  
  10. {% for row in user_list %}
  11. <li>{{ row.name }}</li>
  12. {% endfor %}
  13.  
  14. <nav aria-label="Page navigation">
  15. <ul class="pagination">
  16. {{ page_info.pager |safe }}
  17.  
  18. </ul>
  19. </nav>
  20. </body>
  21. </html>
  22.  
  23. custom.html

custom.html

三、ORM正反向连表操作

  1. #ORM正反向连表操作
  2. - models
  3. from django.db import models
  4.  
  5. class Foo(models.Model):
  6. """
  7. 第三个表
  8. """
  9. caption = models.CharField(max_length=16)
  10.  
  11. class UserType(models.Model):
  12. """
  13. 用户类型
  14. """
  15. title = models.CharField(max_length=32)
  16. fo = models.ForeignKey('Foo')
  17.  
  18. class UserInfo(models.Model):
  19. """
  20. 用户表
  21. """
  22. name = models.CharField(max_length=16)
  23. age = models.IntegerField()
  24. ut = models.ForeignKey('UserType')
  25.  
  26. - views
  27. ----#跨表(正向操作)---UserInfo----含ForeignKey字段 PS: 一个用户只有一个用户类型
  28. # 获取
  29. # QuerySet[obj,obj,obj]
  30. result = models.UserInfo.objects.all()
  31. for obj in result:
  32. print(obj.name,obj.age,obj.ut_id,obj.ut.title,obj.ut.fo.caption)
  33.  
  34. ----#跨表(反向操作)---UserType----不含ForeignKey字段 PS: 一个用户类型下可以有很多用户
  35.  
  36. obj = models.UserType.objects.all().first()
  37. print('用户类型',obj.id,obj.title)
  38. for row in obj.userinfo_set.all(): #使用的是与之关联的表名小写加_set.all()这个方法取到所有东西
  39. print(row.name,row.age)

四、数据获取多个数据时(注意3种情况的不同之处<跨表查询、跨表取值>)

  1. # 数据获取多个数据时(注意3种情况的不同之处<跨表查询、跨表取值>)
  2. 1. [obj,obj,obj,] # .all()和.filter()拿到的结果是QuerySet对象
  3. models.UserInfo.objects.all()
  4. models.UserInfo.objects.filter(id__gt=1)
  5. result = models.UserInfo.objects.all()
  6. for item in result:
  7. print(item.name,item.ut.title) # 取值方式:item.name,item.ut.title 可以跨表
  8.  
  9. 2. [{id:1,name:fd},{id:1,name:fd},{id:1,name:fd},] # .values()拿到的结果是字典
  10. models.UserInfo.objects.all().values('id','name')
  11. models.UserInfo.objects.filter(id__gt=1).values('id','name')
  12. #无法跨表
  13. result = models.UserInfo.objects.all().values('id','name')
  14. for item in result:
  15. print(item['id'],item['name']) # 取值方式:item['id'],item['name'] #无法跨表
  16. #跨表 使用__(双下划线)
  17. result = models.UserInfo.objects.all().values('id','name',"ut__title") # 这里查询时跨表使用的是ut__title 双下划线
  18. for item in result:
  19. print(item['id'],item['name'],item['ut__title']) # 跨表取值时也用的是双下滑线__
  20.  
  21. 3. [(1,df),(2,'df')] # .values_list()拿到的结果是元组
  22. models.UserInfo.objects.all().values_list('id','name')
  23. models.UserInfo.objects.filter(id__gt=1).values_list('id','name')
  24. #无法跨表
  25. result = models.UserInfo.objects.all().values_list('id','name')
  26. for item in result:
  27. print(item[0],item[1]) # 取值方式: item[0],item[1] #无法跨表
  28. #跨表 使用__(双下划线)
  29. result = models.UserInfo.objects.all().values_list('id','name',"ut__title") # 这里要跨表使用的是ut__title 双下划线
  30. for item in result:
  31. print(item[0],item[1],item[2]) # 跨表取值时用的是下标

五、CSRF(跨站请求伪造)

  1. CSRFCross-site request forgery)跨站请求伪造,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS
  2. 但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。
  3.  
  4. 理解:csrf_token防止从别的网站向自己网站发post请求, 客户来访问网站,网站会向客户发送随机字符串,然后客户带随机字符串发送post请求
  5. 只有带随机字符串来,网站才认,一般是post请求才要求带随机字符串,其它网站第一次来不会带随机字符串。

a. django开启csrf

  1. MIDDLEWARE = [
  2. 'django.middleware.csrf.CsrfViewMiddleware',
  3. ]

b.HTML中使用

  1. {% csrf_token %} #只要写上{% csrf_token %} 会有一个隐藏的input随机字符串,在cookie也有一个随机的字符串,form表单提交数据时,一般会使用
  2. {{ csrf_token }} #生成随机的字符串

c.django中设置防跨站请求伪造功能有分为全局和局部

  1. #局部
  2.  
  3. from django.views.decorators.csrf import csrf_exempt,csrf_protect
  4.  
  5. @csrf_protect settings中没有设置全局中间件,为当前函数强制设置防跨站请求伪造功能。
  6. @csrf_exempt settings中设置了全局中间件,取消当前函数防跨站请求伪造功能。
  1. #fbv
  2.  
  3. @csrf_protect
  4. def func(object):
  5. pass
  6.  
  7. #cbv
  8.  
  9. from django.views import View
  10. from django.utils.decorators import method_decorator
  11.  
  12. @method_decorator(csrf_exempt,name="dispatch")
  13. class foo(View)
  14. pass
  15.  
  16. fbvcbv应用装饰器

fbv和cbv应用装饰器

  1. #方式一 类上加装饰器:
  2.  
  3. def wrapper(func):
  4. def inner(*args,**kwargs):
  5. return func(*args,**kwargs)
  6. return inner
  7.  
  8. @method_decorator(wrapper,name="get")
  9. @method_decorator(wrapper,name="post")
  10. class foo(View):
  11.  
  12. def get(self,request):
  13. pass
  14.  
  15. def post(self,request):
  16. pass
  17.  
  18. #方式二 类上“dispatch”加装饰器:
  19.  
  20. def wrapper(func):
  21. def inner(*args,**kwargs):
  22. return func(*args,**kwargs)
  23. return inner
  24.  
  25. @method_decorator(wrapper,name="dispatch")
  26. class foo(View):
  27.  
  28. def dispatch(self,request,*args,**kwargs):
  29. return xxx
  30.  
  31. def get(self,request):
  32. pass
  33.  
  34. def post(self,request):
  35. pass
  36.  
  37. #方式三 方法上加装饰器:
  38.  
  39. def wrapper(func):
  40. def inner(*args,**kwargs):
  41. return func(*args,**kwargs)
  42. return inner
  43.  
  44. class foo(View):
  45.  
  46. @method_decorator(wrapper)
  47. def get(self,request):
  48. pass
  49.  
  50. def post(self,request):
  51. pass
  52.  
  53. cbv应用其它装饰器

cbv应用其它装饰器

d. Ajax提交数据 携带CSRF

1. 通过获取隐藏的input标签中的字符串,放置在data中发送

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <form method="POST" action="/csrf1.html">
  9. {% csrf_token %}
  10. <input id="user" type="text" name="user"/>
  11. <a onclick="submitForm();">Ajax提交</a>
  12. </form>
  13.  
  14. <script src="/static/jquery-1.12.4.js"></script>
  15. <script>
  16. function submitForm() {
  17. var csrf = $('input[name="csrfmiddlewaretoken"]').val();
  18. var user = $("#user").val();
  19. $.ajax({
  20. url:'/csrf1.html',
  21. type:'POST',
  22. data:{"user":user,"csrfmiddlewaretoken":csrf},
  23. success:function (arg) {
  24. console.log(arg);
  25. }
  26.  
  27. })
  28. }
  29. </script>
  30.  
  31. </body>
  32. </html>
  33.  
  34. csrf1.html

csrf1.html

  1. urlpatterns = [
  2.  
  3. url(r'^csrf1.html', views.csrf1),
  4. ]

urls.py

  1. def csrf1(request):
  2.  
  3. if request.method == 'GET':
  4. return render(request,'csrf1.html')
  5. else:
  6. return HttpResponse('ok')

views.py

2. 通过获取返回的cookie中的字符串,放置在请求头中发送

  1. 通过在console document.cookie可以获取 csrftoken=JPv1gIdrBiAlK2RCrgFs0OKwsncPXvwPfMhEWIVzMdMFymIayiuGu2GkBAu57moL
  2. 但需要切割字符串,通过引入jquery.cookie.jscookie操作,使用$.cookie("csrftoken")
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <form method="POST" action="/csrf1.html">
  9. {% csrf_token %}
  10. <input id="user" type="text" name="user"/>
  11. <a onclick="submitForm();">Ajax提交</a>
  12. </form>
  13.  
  14. <script src="/static/jquery-1.12.4.js"></script>
  15. <script src="/static/jquery.cookie.js"></script>
  16. <script>
  17. function submitForm() {
  18. var token = $.cookie("csrftoken");
  19. var user = $("#user").val();
  20. $.ajax({
  21. url:'/csrf1.html',
  22. type:'POST',
  23. headers:{"X-CSRFToken":token},
  24. data:{"user":user},
  25. success:function (arg) {
  26. console.log(arg);
  27. }
  28.  
  29. })
  30. }
  31. </script>
  32.  
  33. </body>
  34. </html>
  35.  
  36. csrf1.html

csrf1.html

六、Django框架最最最最基础的3+5基本使用步骤 。◕‿◕。

  1. 1,创建项目文件夹
  2. 在终端Terminal执行命令:
  3. django-admin startproject 项目名
  4.  
  5. 2,配置3个地方
  6. (1)模板路径配置
  7. TEMPLATES = [
  8. {
  9. 'BACKEND': 'django.template.backends.django.DjangoTemplates',
  10. 'DIRS': [os.path.join(BASE_DIR,'templates')], # 这一步
  11. 'APP_DIRS': True,
  12. 'OPTIONS': {
  13. 'context_processors': [
  14. 'django.template.context_processors.debug',
  15. 'django.template.context_processors.request',
  16. 'django.contrib.auth.context_processors.auth',
  17. 'django.contrib.messages.context_processors.messages',
  18. ],
  19. },
  20. },
  21. ]
  22. (2) 静态文件配置
  23. STATIC_URL = '/static/'
  24. STATICFILES_DIRS = (
  25. os.path.join(BASE_DIR,'static'),
  26. )
  27.  
  28. (3) # 'django.middleware.csrf.CsrfViewMiddleware', 注释这一行
  29.  
  30. 3,Django框架5
  31. 在终端Terminal执行命令创建app模块:
  32. python manage.py startapp 模块名
  33.  
  34. (1)连接数据库
  35. DATABASES = {
  36. 'default': {
  37. 'ENGINE': 'django.db.backends.mysql',
  38. 'NAME': "studentPro",
  39. 'USER':'yangzai',
  40. 'PASSWORD':'Oldsyang=5201314@yangzai',
  41. 'HOST':'mypy.me',
  42. 'PORT':3306,
  43. }
  44. }
  45.  
  46. (2)导入pymysql
  47. __init__中写入
  48. import pymysql
  49. pymysql.install_as_MySQLdb()
  50.  
  51. (3)创建model
  52. from django.db import models
  53. class UserInfo(models.Model):
  54. id =
  55. name =
  56. password =
  57.  
  58. (4)注册模块
  59. INSTALLED_APPS = [
  60. 'django.contrib.admin',
  61. 'django.contrib.auth',
  62. 'django.contrib.contenttypes',
  63. 'django.contrib.sessions',
  64. 'django.contrib.messages',
  65. 'django.contrib.staticfiles',
  66. 'app01' -----这一步
  67. ]
  68.  
  69. (5)初始化数据库
  70. python manage.py makemigrations --先执行
  71.   python manage.py migrate --后执行
  72.  
  73. 基本使用步骤

基本使用步骤

七、Django框架里面return的3种返回

  1. return render() - 返回页面
  2. - return render(request,'index.html',{'std_list':std_list})
  3. 3个参数含义:
  4. request:用户的请求信息
  5. 'index.html':需要返回的模板html页面
  6. {'std_list':std_list}:存放模板文件里面要被替换的占位符所对应的值
  7.  
  8. return HttpResponse() - 返回字符串
  9. - return HttpResponse(json.dumps(ret))
  10.  
  11. return redirect() - 返回url请求
  12. - return redirect('/teachers/')
  13.  
  14. 提示点:redirecthrefaction,这3url请求,都要在地址前加/斜杠
  15. 例子:return redirect('/classes.html')
  16. <a href="/edit_class/{{ row.id }}.html">
  17. <form method="POST" action="/edit_class/{{ id }}.html">
  18.  
  19. return3中返回

return的3中返回

八、cookie

a. 简单应用

  1. def login(request):
  2. if request.method=="GET":
  3. return render(request,"login.html")
  4. else:
  5. name = request.POST.get("name")
  6. password = request.POST.get("password")
  7. if name == "alex" and password == "":
  8. obj = redirect("/classes/")
  9. obj.set_cookie("ticket","",max_age=10)
  10. return obj
  11. else:
  12. return redirect("/login/")
  13.  
  14. def classes(request):
  15. sk = request.COOKIES
  16. print(sk)
  17. if not sk:
  18. return redirect("/login/")

b. 过期时间的两种格式

  1. 方式一:
  2. obj.set_cookie("ticket","",max_age=10)
  3.  
  4. 方式二:
  5. import datetime
  6. from datetime import timedelta #时间的加减
  7. ct = datetime.datetime.utcnow() #获取当前日期
  8. v= timedelta(seconds=10) #10秒
  9. value = ct + v
  10.  
  11. obj.set_cookie("ticket","",expires=value)

c. 限制路径

  1. obj.set_cookie("ticket","",max_age=10,path="/") #所有路径都可以访问
  2.  
  3. obj.set_cookie("ticket","",max_age=10,path="/class") #只有class访问

d. cookie签名

  1. #加
  2. obj.set_signed_cookie("ticket","",salt="abc")
  3.  
  4. #解
  5. sk = request.get_signed_cookie("ticket",salt="abc")

九、session

  1. 流程:客户登录网址,验证成功后,服务端生成一个随机字符串和随机字符串对应的键值,然后把随机字符串通过cookie发送给客户端
  2. 客户端拿着随机字符串通过cookir再次登陆,服务端拿着随机字符串和保存在本地的数据对应,以确定用户的登录状态
  1. Cookie是什么?
  2. 保存在客户端浏览器上的键值对
  3. Session是什么?
  4. 保存在服务端的数据(本质是键值对)
  5. {
  6. aaaaa":{'id':1,'name':'于浩',email='xxxx'}
  7. "bbbbb":{'id':2,'name':'陈涛',email=''}
  8. }
  9. 应用:依赖cookie
  10. 作用:保持会话(Web网站)
  11. 好处:敏感信息不会直接给客户端
  12.  
  13. 梳理:
  14. 1. 保存在服务端的数据(本质是键值对)
  15. 2. 配置文件中:
  16. - 存储位置
  17. - 超时时间、每次刷新更新时间

session是什么

a. 简单示例

  1. 用户访问http://127.0.0.1:8000/login/
  1. urlpatterns = [
  2.  
  3. url(r'^index/', views.index),
  4. url(r'^login/', views.login),
  5. ]

urls

  1. def login(request):
  2. if request.method == 'GET':
  3. return render(request,'login.html')
  4. else:
  5. u = request.POST.get('user')
  6. p = request.POST.get('pwd')
  7. obj = models.UserAdmin.objects.filter(username=u,password=p).first()
  8. if obj:
  9. # 1. 生成随机字符串
  10. # 2. 通过cookie发送给客户端
  11. # 3. 服务端保存
  12. # {
  13. # 随机字符串1: {'username':'alex','email':x''...}
  14. # }
  15. request.session['username'] = obj.username
  16. return redirect('/index/')
  17. else:
  18. return render(request,'login.html',{'msg':'用户名或密码错误'})
  19.  
  20. def index(request):
  21. # 1. 获取客户端端cookie中的随机字符串
  22. # 2. 去session中查找有没有随机字符
  23. # 3. 去session对应key的value中查看是否有 username
  24. v = request.session.get('username')
  25. if v:
  26. return HttpResponse('登录成功:%s' %v)
  27. else:
  28. return redirect('/login/')
  29.  
  30. views.py

views.py

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8.  
  9. <form action="/login/" method="POST">
  10. <input type="text" name="user">
  11. <input type="text" name="pwd">
  12. <input type="submit" value="提交">{{ msg }}
  13. </form>
  14.  
  15. </body>
  16. </html>
  17.  
  18. login.html

login.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8.  
  9. <h1>index page</h1>
  10.  
  11. </body>
  12. </html>
  13.  
  14. index.html

index.html

自己的基于session登陆代码:

  1. def login(request):
  2. if request.method == "GET":
  3. return render(request, "login.html")
  4. else:
  5. input_code = request.POST.get('code')
  6. session_code = request.session.get('code')
  7. username=request.POST.get("user")
  8. password=request.POST.get("pwd")
  9. if input_code.upper() == session_code.upper():
  10. # obj = models.UserInfo.objects.filter(username=username,password=password).first()
  11. obj = models.UserInfo.objects.filter(username=username,password=password).values("nid","avatar",
  12. "nickname",
  13. "blog__title",
  14. "blog__site").first()
  15. print("obj:",obj)
  16.  
  17. # print("obj.nid:",obj.nid)
  18. if obj:
  19. # nid=obj.nid
  20. # request.session["userinfo"]={"id":nid}
  21. request.session["userinfo"]={"id":obj.get("nid"),"avatar":obj.get("avatar"),
  22. "blogname":obj.get("blog__title"),
  23. "nickname":obj.get("nickname"),"site":obj.get("blog__site")}
  24. # print('.................',request.session['userinfo'])
  25. return redirect("/home_page/home_page.html/")
  26. else:
  27. return render(request, 'login.html', {"msg": "用户名或者密码不对"})
  28. else:
  29. return render(request, 'login.html', {"msg": "验证码错误"})
  30.  
  31. # 退出登陆
  32. def logout(request):
  33. request.session.clear() # 清除session
  34. return redirect('/home_page/home_page.html/')

views

十、URL(路由配置系统)

  1. URL配置(URLconf)就像Django 所支撑网站的目录。它的本质是URL与要为该URL调用的视图函数之间的映射表;你就是以这种方式告诉Django,对于这个URL调用这段代码<br>对于那个URL调用那段代码
  2.  
  3. urlpatterns = [
  4. url(正则表达式, views视图函数,参数,别名),
  5. ]
  6.  
  7. 参数说明:
  8.  
  9. 一个正则表达式字符串
  10. 一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串
  11. 可选的要传递给视图函数的默认参数(字典形式)
  12. 一个可选的name参数

1. 单一路由对应

  1. url(r'^index$', views.index)

2. 基于正则的路由

  1. # $
  2. url(r'^index/(\d{4})$',views.index)
  3.  
  4. #无命名分组
  5. url(r'^index/(\d{4})/(\d{2})',views.index)
  6.  
  7. #有命名分组
  8. url(r'^index/(?P<year>\d{4})/(?P<month>\d{2})',views.index)
  1. ############################无命名
  2.  
  3. #-----------------() 相当于传参数
  4.  
  5. url(r'^index/(\d{4})',views.index)
  6.  
  7. def index(request,arg):
  8. return HttpResponse(arg)
  9.  
  10. #url访问http://127.0.0.1:8000/index/1113
  11.  
  12. #-----------------() 接受两个参数
  13.  
  14. url(r'^index/(\d{4})/(\d{2})',views.index)
  15.  
  16. def index(request,arg,arg1):
  17. return HttpResponse("year: %s month: %s"%(arg,arg1))
  18.  
  19. #url访问http://127.0.0.1:8000/index/2017/06
  20. year: 2017 month: 06
  21.  
  22. ############################有命名
  23. url(r'^index/(?P<year>\d{4})/(?P<month>\d{2})',views.index)
  24.  
  25. def index(request,year,month):
  26. return HttpResponse("year: %s month: %s"%(year,month))
  27.  
  28. #url访问http://127.0.0.1:8000/index/2017/06
  29. year: 2017 month: 06
  30.  
  31. 有无命名分组 演示

有无命名分组 演示

3. 为路由映射设置名称

  1. #应用一:
  2. url(r'^index',views.index,name="arg")
  3.  
  4. {{ url "arg" }} 匹配index
  5. {{ url "arg" i}}
  6.  
  7. #应用二:
  8. reverse反向获取url
  1. ##############根据url反生成名字
  2. from django.shortcuts import reverse
  3.  
  4. url(r'^index',views.index,name="arg")
  5.  
  6. def index(request):
  7. v = reverse("arg")
  8. print(v)
  9. return HttpResponse()
  10.  
  11. #用户访问http://127.0.0.1:8000/index
  12. /index
  13.  
  14. ##############根据url改变url
  15.  
  16. url(r'^index/(\d+)/',views.index,name="n1")
  17.  
  18. def index(request,xx):
  19.  
  20. v = reverse('n1',args=(1,))
  21. print(v)
  22. return HttpResponse("...")
  23.  
  24. #访问http://127.0.0.1:8000/index/222/
  25. /index/1/
  26.  
  27. reverse示例 演示

reverse示例 演示

4. 路由分发

  1. url(r'^app01/',include("app01.urls"))
  2. url(r'^app02/',include("app02.urls"))
  3.  
  4. #没有匹配成功,返回默认页面
  5. url(r'^',include("views.default"))

十一、Model

a. 创建表 

  1. from django.db import models
  2.  
  3. class User_type(models.Model):
  4. uid = models.BigAutoField(primary_key=True)
  5. title = models.CharField(max_length=32)
  6.  
  7. class User_info(models.Model):
  8. name = models.CharField(max_length=32)
  9. age = models.CharField(max_length=32)
  10. ut = models.ForeignKey("User_type")
  11.  
  12. python3 manage.py makemigrations
  13.  
  14. python3 manage.py migrate
  15.  
  16. ---------------------其它---------------------
  17.  
  18. class part(models.Model):
  19. cid = models.BigAutoField(primary_key=True)
  20. title = models.CharField(max_length=32,null=False)
  21.  
  22. class student(models.Model):
  23. sid = models.BigAutoField(primary_key=True)
  24. name = models.CharField(max_length=32,null=False)
  25. pub_data=models.DateField()
  26. age = models.IntegerField(default=18)
  27. # 新增加的列 如果原先表里有值,写default
  28. ug = models.ForeignKey("part",null=True) #如果新增加外键,加null=True

b. ORM操作

  1. #增
  2. # models.User_type.objects.create(title="黑金用户")
  3.  
  4. # obj = models.User_type(title="小白用户")
  5. # obj.save()
  6.  
  7. #删
  8. #models.User_type.objects.filter(title="小白用户").delete() # 删除指定条件的数据
  9.  
  10. #改
  11. #models.User_type.objects.filter(title="黑金用户").update(title="黑卡用户") # 修改指定条件的数据
  12.  
  13. #查
  14. # models.User_type.objects.get(title="大白用户") # 获取单条数据,不存在则报错(不建议)
  15. # models.User_type.objects.all() # 获取全部
  16. # models.User_type.objects.filter(title="小白用户") # 获取指定条件的数据
  17. # models.User_type.objects.exclude(title="黄金用户") # 排除指定条件的数据
  18.  
  19. 基本增删改查

基本增删改查

  1. # 获取个数
  2.  
  3. models.User_info.objects.filter(age=18).count()
  4.  
  5. # 大于 小于
  6.  
  7. # models.Tb1.objects.filter(id__gt=1) # 获取id大于1的值
  8. # models.Tb1.objects.filter(id__gte=1) # 获取id大于等于1的值
  9. # models.Tb1.objects.filter(id__lt=10) # 获取id小于10的值
  10. # models.Tb1.objects.filter(id__lte=10) # 获取id小于10的值
  11. # models.Tb1.objects.filter(id__gt=1,id__lt=10) # 获取id大于1 且 小于10的值
  12.  
  13. #in
  14.  
  15. models.User_info.objects.filter(age__in=[19]) # in
  16. models.User_info.objects.exclude(age__in=[19]) # not in
  17.  
  18. # isnull
  19.  
  20. models.User_info.objects.filter(age__isnull=True) # age列为不为空
  21. models.User_info.objects.filter(age__isnull=False) # age列是不是 不为空
  22.  
  23. # contains
  24.  
  25. # models.Tb1.objects.filter(name__contains="ven")
  26. # models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感
  27. # models.Tb1.objects.exclude(name__icontains="ven")
  28.  
  29. # range
  30.  
  31. # models.Tb1.objects.filter(id__range=[1, 5]) # 范围bettwen and
  32.  
  33. #开始 结束
  34.  
  35. # startswith,istartswith, endswith, iendswith
  36.  
  37. #order_by
  38.  
  39. #models.User_info.objects.all().order_by("id") # asc
  40. #models.User_info.objects.all().order_by("-id") # desc
  41.  
  42. # models.Tb1.objects.filter(name='seven').order_by('id') # asc
  43. # models.Tb1.objects.filter(name='seven').order_by('-id') # desc
  44.  
  45. #group by #后面出现filter代表having
  46.  
  47. from django.db.models import Count
  48. #models.User_info.objects.values("name","age").annotate() #没有起作用
  49. #SELECT "app01_user_info"."name", "app01_user_info"."age" FROM "app01_user_info"
  50.  
  51. #models.User_info.objects.values("age").annotate(xxx=Count("age"))
  52. #SELECT "app01_user_info"."age", COUNT("app01_user_info"."age") AS "xxx" FROM "app01_user_info" GROUP BY "app01_user_info"."age"
  53.  
  54. #models.User_info.objects.values("age").annotate(xxx=Count("age")).filter(xxx__gt=2) #年龄相同次数大于2的查出来
  55. #SELECT "app01_user_info"."age", COUNT("app01_user_info"."age") AS "xxx" FROM "app01_user_info" GROUP BY "app01_user_info"."age" HAVING COUNT("app01_user_info"."age") > 2
  56.  
  57. #注意两次filter 第一次代表where 第二次代表having
  58.  
  59. #models.User_info.objects.filter(id__gt=2).values("age").annotate(xxx=Count("age")).filter(xxx__gt=2)
  60. #SELECT "app01_user_info"."age", COUNT("app01_user_info"."age") AS "xxx" FROM "app01_user_info" WHERE "app01_user_info"."id" > 2 GROUP BY "app01_user_info"."age" HAVING COUNT("app01_user_info"."age") > 2
  61.  
  62. 常用方法

常用方法

  1. # F
  2.  
  3. # from django.db.models import F
  4. # models.User_info.objects.all().update(age=F("age")+5) # age列加5
  5.  
  6. # Q
  7.  
  8. # 方式一:
  9. # Q(nid__gt=10)
  10. # Q(nid=8) | Q(nid__gt=10)
  11. # Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
  12.  
  13. #-------------------------------以下三种查找方式相同效果
  14.  
  15. # obj = models.User_info.objects.filter(id=307,name="egon")
  16.  
  17. # condition ={
  18. # 'id':307,
  19. # 'name':'egon',
  20. # }
  21. # obj = models.User_info.objects.filter(**condition)
  22.  
  23. #obj = models.User_info.objects.filter(Q(id=307) & Q(name="egon"))
  24. ---------------------------------
  25.  
  26. # 方式二:
  27.  
  28. # q1 = Q()
  29. # q1.connector = 'OR'
  30. # q1.children.append(('id', 1))
  31. # q1.children.append(('id', 10))
  32. # q1.children.append(('id', 9))
  33.  
  34. # q2 = Q()
  35. # q2.connector = 'OR'
  36. # q2.children.append(('c1', 1))
  37. # q2.children.append(('c1', 10))
  38. # q2.children.append(('c1', 9))
  39.  
  40. # q3 = Q()
  41. # q3.connector = 'AND'
  42. # q3.children.append(('id', 1))
  43. # q3.children.append(('id', 2))
  44. # q1.add(q3, 'OR')
  45.  
  46. # con = Q()
  47. # con.add(q1, 'AND')
  48. # con.add(q2, 'AND')
  49.  
  50. #(id=1 or id=10 or id=9 or (id=1 and id=2)) and (c1=1 or c1=10 or c1=9) #等于上面
  51.  
  52. # models.Tb1.objects.filter(con)
  53.  
  54. # Q演示
  55. condition_dict = {
  56. 'k1':[1,2,3,4],
  57. 'k2':[1,],
  58. 'k3':[11,]
  59. }
  60.  
  61. con = Q()
  62. for k,v in condition_dict.items():
  63. q = Q()
  64. q.connector = 'OR'
  65. for i in v:
  66. q.children.append(('id',1))
  67. con.add(q,'AND')
  68.  
  69. models.User_info.objects.filter(con)
  70.  
  71. F Q 演示

F Q 演示

c. 多对多操作

方式一:通过外键创建第三张表

  1. class Boy(models.Model):
  2. name = models.CharField(max_length=32)
  3.  
  4. class Girl(models.Model):
  5. nick = models.CharField(max_length=32)
  6.  
  7. class Love(models.Model):
  8. b = models.ForeignKey("Boy")
  9. g = models.ForeignKey("Girl")
  10.  
  11. class Meta:
  12. unique_together = [
  13. ("b","g"),
  14. ]
  1. #表里插入数据
  2.  
  3. objs = [
  4. models.Boy(name='方少伟'),
  5. models.Boy(name='游勤斌'),
  6. models.Boy(name='于浩'),
  7. models.Boy(name='陈涛'),
  8. ]
  9. models.Boy.objects.bulk_create(objs,4)
  10.  
  11. result = [
  12. models.Girl(nick='于浩姐姐'),
  13. models.Girl(nick='景甜'),
  14. models.Girl(nick='刘亦非'),
  15. models.Girl(nick='苍老师'),
  16. ]
  17. models.Girl.objects.bulk_create(result, 4)
  18.  
  19. models.Love.objects.create(b_id=1,g_id=1)
  20. models.Love.objects.create(b_id=1,g_id=2)
  21. models.Love.objects.create(b_id=1,g_id=3)
  22. models.Love.objects.create(b_id=2,g_id=4)
  23.  
  24. ################### 查找和我有关系的女孩 四种方式 ################
  25.  
  26. obj = models.Boy.objects.filter(name="方少伟").first()
  27. love_list = obj.love_set.all()
  28. for row in love_list:
  29. print(row.g.nick)
  30.  
  31. love_list = models.Love.objects.filter(b__name="方少伟")
  32. for row in love_list:
  33. print(row.g.nick)
  34.  
  35. #下面两个效果好
  36.  
  37. love_list = models.Love.objects.filter(b__name="方少伟").values("g__nick")
  38. for item in love_list:
  39. print(item["g__nick"])
  40.  
  41. love_list = models.Love.objects.filter(b__name="方少伟").select_related("g")
  42. for obj in love_list:
  43. print(obj.g.nick)
  44.  
  45. SQL演示

SQL演示

方式二:通过 ManyToManyField 创建第三张表

  1. class Boy(models.Model):
  2. name = models.CharField(max_length=32)
  3. m = models.ManyToManyField("Girl")
  4.  
  5. class Girl(models.Model):
  6. nick = models.CharField(max_length=32)
  1. obj = models.Boy.objects.filter(name="方少伟").first()
  2. # print(obj.id,obj.name)
  3.  
  4. # obj.m.add(2)
  5. # obj.m.add(1,3)
  6. # obj.m.add(*[4,])
  7.  
  8. # obj.m.remove(2)
  9. # obj.m.remove(1,3)
  10. # obj.m.remove(*[4,])
  11.  
  12. # obj.m.set([1,4,])
  13.  
  14. # girl_list = obj.m.all()
  15. # girl_list = obj.m.filter(nick="苍老师")
  16.  
  17. # obj.m.clear()
  18.  
  19. obj = models.Girl.objects.filter(nick="苍老师").first()
  20. v = obj.boy_set.all()
  21.  
  22. SQL 演示

SQL 演示

方式三:通过 外键 和 ManyToManyField 创建

  1. class Boy(models.Model):
  2. name = models.CharField(max_length=32)
  3. m = models.ManyToManyField("Girl",through="Love",through_fields=("b","g",))
  4.  
  5. class Girl(models.Model):
  6. nick = models.CharField(max_length=32)
  7.  
  8. class Love(models.Model):
  9. b = models.ForeignKey("Boy")
  10. g = models.ForeignKey("Girl")
  11.  
  12. class Meta:
  13. unique_together = [
  14. ("b","g"),
  15. ]
  1. obj = models.Boy.objects.filter(name="方少伟").first()
  2.  
  3. #只可以查或清空
  4. obj.m.clear()
  5.  
  6. obj.m.all()
  7.  
  8. SQL 操作

SQL 操作

d. 一对多

  1. 正向:
  2. filter() values,values_list() -> 跨表 fk__xxx
  3. objs = all()
  4. for obj in objs:
  5. obj.fk.
  6. 反向:
  7. filter() values,values_list() -> 跨表 表名称__xxx
  8. objs = all()
  9. for obj in objs:
  10. obj.表名称_set.all()

1.连表操作演示

  1. urlpatterns = [
  2.  
  3. url(r'^test/', views.test),
  4.  
  5. ]

urls

  1. class User_type(models.Model):
  2. uid = models.BigAutoField(primary_key=True)
  3. title = models.CharField(max_length=32)
  4.  
  5. class User_info(models.Model):
  6. name = models.CharField(max_length=32)
  7. age = models.CharField(max_length=32)
  8. ut = models.ForeignKey("User_type")
  9.  
  10. models.py

models.py

  1. def test(request):
  2. models.User_type.objects.create(title="普通用户")
  3. models.User_type.objects.create(title="白金用户")
  4. models.User_type.objects.create(title="黄金用户")
  5.  
  6. models.User_info.objects.create(name="小鸡",age=18,ut_id=1)
  7. models.User_info.objects.create(name="小狗",age=18,ut_id=2)
  8. models.User_info.objects.create(name="小猫",age=18,ut_id=2)
  9. models.User_info.objects.create(name="小雨",age=18,ut_id=3)
  10. models.User_info.objects.create(name="大雨",age=18,ut_id=1)
  11.  
  12. for i in range(300):
  13. name = "root" + str(i)
  14. models.User_info.objects.create(name=name, age=18, ut_id=1)
  15.  
  16. #正向操作
  17. obj = models.User_info.objects.all().first()
  18. print(obj.name,obj.age,obj.ut.title)
  19.  
  20. #反向操作 obj.表名小写_set.all()
  21. obj = models.User_type.objects.all().first()
  22. for row in obj.user_info_set.all():
  23. print(row.name,row.age)
  24.  
  25. result = models.User_type.objects.all()
  26. for item in result:
  27. print(item.title,item.user_info_set.all())
  28. print(item.user_info_set.filter(name="小雨"))
  29.  
  30. #字典格式
  31. result = models.User_info.objects.all().values("id","name")
  32. for row in result:
  33. print(row)
  34.  
  35. #字典格式查的时候跨表
  36. result = models.User_info.objects.all().values("id","name","ut__title")
  37. for row in result:
  38. print(row["id"],row["name"],row["ut__title"])
  39.  
  40. # 元组格式
  41. # result = models.User_info.objects.all().values_list("id","name")
  42. # for row in result:
  43. # print(row)
  44.  
  45. return HttpResponse(".....")
  46.  
  47. views.py

views.py

十二、ORM操作

  1. 操作数据行:---------(在views中操作)

  2. models.Tb1.objects.create(c1='xx', c2='oo') 增加一条数据,可以接受字典类型数据 **kwargs
  3. obj = models.Tb1(c1='xx', c2='oo')
  4. obj.save()
  5.  

  6. models.Tb1.objects.filter(name='seven').delete() # 删除指定条件的数据
  7.  

  8. models.Tb1.objects.filter(name='seven').update(gender='') # 将指定条件的数据更新,均支持 **kwargs
  9. obj = models.Tb1.objects.get(id=1)
  10. obj.c1 = ''
  11. obj.save() # 修改单条数据
  12.  

  13. models.Tb1.objects.get(id=123) # 获取单条数据,不存在则报错(不建议)
  14. models.Tb1.objects.all() # 获取全部
  15. models.Tb1.objects.filter(name='seven') # 获取指定条件的数据

基本增、删、改、查

  1. # 获取个数
  2. #
  3. # models.Tb1.objects.filter(name='seven').count()
  4.  
  5. # 大于,小于
  6. #
  7. # models.Tb1.objects.filter(id__gt=1) # 获取id大于1的值
  8. # models.Tb1.objects.filter(id__gte=1) # 获取id大于等于1的值
  9. # models.Tb1.objects.filter(id__lt=10) # 获取id小于10的值
  10. # models.Tb1.objects.filter(id__lte=10) # 获取id小于10的值
  11. # models.Tb1.objects.filter(id__lt=10, id__gt=1) # 获取id大于1 且 小于10的值
  12.  
  13. # in
  14. #
  15. # models.Tb1.objects.filter(id__in=[11, 22, 33]) # 获取id等于11、22、33的数据
  16. # models.Tb1.objects.exclude(id__in=[11, 22, 33]) # not in
  17.  
  18. # isnull
  19. # Entry.objects.filter(pub_date__isnull=True)
  20.  
  21. # contains
  22. #
  23. # models.Tb1.objects.filter(name__contains="ven")
  24. # models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感
  25. # models.Tb1.objects.exclude(name__icontains="ven")
  26.  
  27. # range
  28. #
  29. # models.Tb1.objects.filter(id__range=[1, 2]) # 范围bettwen and
  30.  
  31. # 其他类似
  32. #
  33. # startswith,istartswith, endswith, iendswith,
  34.  
  35. # order by
  36. #
  37. # models.Tb1.objects.filter(name='seven').order_by('id') # asc
  38. # models.Tb1.objects.filter(name='seven').order_by('-id') # desc
  39.  
  40. # group by
  41. #
  42. # from django.db.models import Count, Min, Max, Sum
  43. # models.Tb1.objects.filter(c1=1).values('id').annotate(c=Count('num'))
  44. # SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id"
  45.  
  46. # limit 、offset
  47. #
  48. # models.Tb1.objects.all()[10:20]
  49.  
  50. # regex正则匹配,iregex 不区分大小写
  51. #
  52. # Entry.objects.get(title__regex=r'^(An?|The) +')
  53. # Entry.objects.get(title__iregex=r'^(an?|the) +')
  54.  
  55. # date
  56. #
  57. # Entry.objects.filter(pub_date__date=datetime.date(2005, 1, 1))
  58. # Entry.objects.filter(pub_date__date__gt=datetime.date(2005, 1, 1))
  59.  
  60. # year
  61. #
  62. # Entry.objects.filter(pub_date__year=2005)
  63. # Entry.objects.filter(pub_date__year__gte=2005)
  64.  
  65. # month
  66. #
  67. # Entry.objects.filter(pub_date__month=12)
  68. # Entry.objects.filter(pub_date__month__gte=6)
  69.  
  70. # day
  71. #
  72. # Entry.objects.filter(pub_date__day=3)
  73. # Entry.objects.filter(pub_date__day__gte=3)
  74.  
  75. # week_day
  76. #
  77. # Entry.objects.filter(pub_date__week_day=2)
  78. # Entry.objects.filter(pub_date__week_day__gte=2)
  79.  
  80. # hour
  81. #
  82. # Event.objects.filter(timestamp__hour=23)
  83. # Event.objects.filter(time__hour=5)
  84. # Event.objects.filter(timestamp__hour__gte=12)
  85.  
  86. # minute
  87. #
  88. # Event.objects.filter(timestamp__minute=29)
  89. # Event.objects.filter(time__minute=46)
  90. # Event.objects.filter(timestamp__minute__gte=29)
  91.  
  92. # second
  93. #
  94. # Event.objects.filter(timestamp__second=31)
  95. # Event.objects.filter(time__second=2)
  96. # Event.objects.filter(timestamp__second__gte=31)

操作---进阶

  1. # extra #额外查询条件以及相关表,排序
  2. #
  3. # extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None)
  4. # a. 映射
  5. # select
  6. # select_params=None
  7. # select 此处 from 表
  8.  
  9. # b. 条件
  10. # where=None
  11. # params=None,
  12. # select * from 表 where 此处
  13.  
  14. # c. 表
  15. # tables
  16. # select * from 表,此处
  17.  
  18. # c. 排序
  19. # order_by=None
  20. # select * from 表 order by 此处
  21.  
  22. # Entry.objects.extra(select={'new_id': "select col from sometable where othercol > %s"}, select_params=(1,))
  23. # Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
  24. # Entry.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'"])
  25. # Entry.objects.extra(select={'new_id': "select id from tb where id > %s"}, select_params=(1,), order_by=['-nid'])
  26.  
  27. # F #更新时用于获取原来的值
  28.  
  29. from django.db.models import F
  30. models.Tb1.objects.update(num=F('num')+1)
  31.  
  32. # Q #用于构造复杂查询条件
  33.  
  34. # 应用一:
  35. models.UserInfo.objects.filter(Q(id__gt=1))
  36. models.UserInfo.objects.filter(Q(id=8) | Q(id=2))
  37. models.UserInfo.objects.filter(Q(id=8) & Q(id=2))
  38.  
  39. # 应用二:
  40. # con = Q()
  41. # q1 = Q()
  42. # q1.connector = 'OR'
  43. # q1.children.append(('id', 1))
  44. # q1.children.append(('id', 10))
  45. # q1.children.append(('id', 9))
  46. # q2 = Q()
  47. # q2.connector = 'OR'
  48. # q2.children.append(('c1', 1))
  49. # q2.children.append(('c1', 10))
  50. # q2.children.append(('c1', 9))
  51. # con.add(q1, 'AND')
  52. # con.add(q2, 'AND')
  53. #
  54. # models.Tb1.objects.filter(con)
  55.  
  56. # 执行原生SQL
  57. #
  58. # from django.db import connection, connections
  59. # cursor = connection.cursor() # cursor = connections['default'].cursor()
  60. # cursor.execute("""SELECT * from auth_user where id = %s""", [1])
  61. # row = cursor.fetchone()

操级---高级

  1. ##################################################################
  2. # PUBLIC METHODS THAT ALTER ATTRIBUTES AND RETURN A NEW QUERYSET #
  3. ##################################################################
  4.  
  5. def all(self)
  6. # 获取所有的数据对象
  7.  
  8. def filter(self, *args, **kwargs)
  9. # 条件查询
  10. # 条件可以是:参数,字典,Q
  11.  
  12. def exclude(self, *args, **kwargs)
  13. # 条件查询
  14. # 条件可以是:参数,字典,Q
  15.  
  16. def select_related(self, *fields)
  17. 性能相关:表之间进行join连表操作,一次性获取关联的数据。
  18. model.tb.objects.all().select_related()
  19. model.tb.objects.all().select_related('外键字段')
  20. model.tb.objects.all().select_related('外键字段__外键字段')
  21.  
  22. def prefetch_related(self, *lookups)
  23. 性能相关:多表连表操作时速度会慢,使用其执行多次SQL查询在Python代码中实现连表操作。
  24. # 获取所有用户表
  25. # 获取用户类型表where id in (用户表中的查到的所有用户ID)
  26. models.UserInfo.objects.prefetch_related('外键字段')
  27.  
  28. from django.db.models import Count, Case, When, IntegerField
  29. Article.objects.annotate(
  30. numviews=Count(Case(
  31. When(readership__what_time__lt=treshold, then=1),
  32. output_field=CharField(),
  33. ))
  34. )
  35.  
  36. students = Student.objects.all().annotate(num_excused_absences=models.Sum(
  37. models.Case(
  38. models.When(absence__type='Excused', then=1),
  39. default=0,
  40. output_field=models.IntegerField()
  41. )))
  42.  
  43. def annotate(self, *args, **kwargs)
  44. # 用于实现聚合group by查询
  45.  
  46. from django.db.models import Count, Avg, Max, Min, Sum
  47.  
  48. v = models.UserInfo.objects.values('u_id').annotate(uid=Count('u_id'))
  49. # SELECT u_id, COUNT(ui) AS `uid` FROM UserInfo GROUP BY u_id
  50.  
  51. v = models.UserInfo.objects.values('u_id').annotate(uid=Count('u_id')).filter(uid__gt=1)
  52. # SELECT u_id, COUNT(ui_id) AS `uid` FROM UserInfo GROUP BY u_id having count(u_id) > 1
  53.  
  54. v = models.UserInfo.objects.values('u_id').annotate(uid=Count('u_id',distinct=True)).filter(uid__gt=1)
  55. # SELECT u_id, COUNT( DISTINCT ui_id) AS `uid` FROM UserInfo GROUP BY u_id having count(u_id) > 1
  56.  
  57. def distinct(self, *field_names)
  58. # 用于distinct去重
  59. models.UserInfo.objects.values('nid').distinct()
  60. # select distinct nid from userinfo
  61.  
  62. 注:只有在PostgreSQL中才能使用distinct进行去重
  63.  
  64. def order_by(self, *field_names)
  65. # 用于排序
  66. models.UserInfo.objects.all().order_by('-id','age')
  67.  
  68. def extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None)
  69. # 构造额外的查询条件或者映射,如:子查询
  70.  
  71. Entry.objects.extra(select={'new_id': "select col from sometable where othercol > %s"}, select_params=(1,))
  72. Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
  73. Entry.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'"])
  74. Entry.objects.extra(select={'new_id': "select id from tb where id > %s"}, select_params=(1,), order_by=['-nid'])
  75.  
  76. def reverse(self):
  77. # 倒序
  78. models.UserInfo.objects.all().order_by('-nid').reverse()
  79. # 注:如果存在order_by,reverse则是倒序,如果多个排序则一一倒序
  80.  
  81. def defer(self, *fields):
  82. models.UserInfo.objects.defer('username','id')

  83. models.UserInfo.objects.filter(...).defer('username','id')
  84. #映射中排除某列数据
  85.  
  86. def only(self, *fields):
  87. #仅取某个表中的数据
  88. models.UserInfo.objects.only('username','id')

  89. models.UserInfo.objects.filter(...).only('username','id')
  90.  
  91. def using(self, alias):
  92. 指定使用的数据库,参数为别名(setting中的设置)
  93.  
  94. ##################################################
  95. # PUBLIC METHODS THAT RETURN A QUERYSET SUBCLASS #
  96. ##################################################
  97.  
  98. def raw(self, raw_query, params=None, translations=None, using=None):
  99. # 执行原生SQL
  100. models.UserInfo.objects.raw('select * from userinfo')
  101.  
  102. # 如果SQL是其他表时,必须将名字设置为当前UserInfo对象的主键列名
  103. models.UserInfo.objects.raw('select id as nid from 其他表')
  104.  
  105. # 为原生SQL设置参数
  106. models.UserInfo.objects.raw('select id as nid from userinfo where nid>%s', params=[12,])
  107.  
  108. # 将获取的到列名转换为指定列名
  109. name_map = {'first': 'first_name', 'last': 'last_name', 'bd': 'birth_date', 'pk': 'id'}
  110. Person.objects.raw('SELECT * FROM some_other_table', translations=name_map)
  111.  
  112. # 指定数据库
  113. models.UserInfo.objects.raw('select * from userinfo', using="default")
  114.  
  115. ################### 原生SQL ###################
  116. from django.db import connection, connections
  117. cursor = connection.cursor() # cursor = connections['default'].cursor()
  118. cursor.execute("""SELECT * from auth_user where id = %s""", [1])
  119. row = cursor.fetchone() # fetchall()/fetchmany(..)
  120.  
  121. def values(self, *fields):
  122. # 获取每行数据为字典格式
  123.  
  124. def values_list(self, *fields, **kwargs):
  125. # 获取每行数据为元祖
  126.  
  127. def dates(self, field_name, kind, order='ASC'):
  128. # 根据时间进行某一部分进行去重查找并截取指定内容
  129. # kind只能是:"year"(年), "month"(年-月), "day"(年-月-日)
  130. # order只能是:"ASC" "DESC"
  131. # 并获取转换后的时间
  132. - year : 年-01-01
  133. - month: 年-月-01
  134. - day : 年-月-日
  135.  
  136. models.DatePlus.objects.dates('ctime','day','DESC')
  137.  
  138. def datetimes(self, field_name, kind, order='ASC', tzinfo=None):
  139. # 根据时间进行某一部分进行去重查找并截取指定内容,将时间转换为指定时区时间
  140. # kind只能是 "year", "month", "day", "hour", "minute", "second"
  141. # order只能是:"ASC" "DESC"
  142. # tzinfo时区对象
  143. models.DDD.objects.datetimes('ctime','hour',tzinfo=pytz.UTC)
  144. models.DDD.objects.datetimes('ctime','hour',tzinfo=pytz.timezone('Asia/Shanghai'))
  145.  
  146. """
  147. pip3 install pytz
  148. import pytz
  149. pytz.all_timezones
  150. pytz.timezone(‘Asia/Shanghai’)
  151. """
  152.  
  153. def none(self):
  154. # 空QuerySet对象
  155.  
  156. ####################################
  157. # METHODS THAT DO DATABASE QUERIES #
  158. ####################################
  159.  
  160. def aggregate(self, *args, **kwargs):
  161. # 聚合函数,获取字典类型聚合结果
  162. from django.db.models import Count, Avg, Max, Min, Sum
  163. result = models.UserInfo.objects.aggregate(k=Count('u_id', distinct=True), n=Count('nid'))
  164. ===> {'k': 3, 'n': 4}
  165.  
  166. def count(self):
  167. # 获取个数
  168.  
  169. def get(self, *args, **kwargs):
  170. # 获取单个对象
  171.  
  172. def create(self, **kwargs):
  173. # 创建对象
  174.  
  175. def bulk_create(self, objs, batch_size=None):
  176. # 批量插入
  177. # batch_size表示一次插入的个数
  178. objs = [
  179. models.DDD(name='r11'),
  180. models.DDD(name='r22')
  181. ]
  182. models.DDD.objects.bulk_create(objs, 10)
  183.  
  184. def get_or_create(self, defaults=None, **kwargs):
  185. # 如果存在,则获取,否则,创建
  186. # defaults 指定创建时,其他字段的值
  187. obj, created = models.UserInfo.objects.get_or_create(username='root1', defaults={'email': '','u_id': 2, 't_id': 2})
  188.  
  189. def update_or_create(self, defaults=None, **kwargs):
  190. # 如果存在,则更新,否则,创建
  191. # defaults 指定创建时或更新时的其他字段
  192. obj, created = models.UserInfo.objects.update_or_create(username='root1', defaults={'email': '','u_id': 2, 't_id': 1})
  193.  
  194. def first(self):
  195. # 获取第一个
  196.  
  197. def last(self):
  198. # 获取最后一个
  199.  
  200. def in_bulk(self, id_list=None):
  201. # 根据主键ID进行查找
  202. id_list = [11,21,31]
  203. models.DDD.objects.in_bulk(id_list)
  204.  
  205. def delete(self):
  206. # 删除
  207.  
  208. def update(self, **kwargs):
  209. # 更新
  210.  
  211. def exists(self):
  212. # 是否有结果
  213.  
  214. 其他操作

其他操作

十三、多表关系以及参数

  1. ForeignKey(ForeignObject) # ForeignObject(RelatedField)
  2. to, # 要进行关联的表名
  3. to_field=None, # 要关联的表中的字段名称
  4. on_delete=None, # 当删除关联表中的数据时,当前表与其关联的行的行为
  5. - models.CASCADE,删除关联数据,与之关联也删除
  6. - models.DO_NOTHING,删除关联数据,引发错误IntegrityError
  7. - models.PROTECT,删除关联数据,引发错误ProtectedError
  8. - models.SET_NULL,删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空)
  9. - models.SET_DEFAULT,删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值)
  10. - models.SET,删除关联数据,
  11. a. 与之关联的值设置为指定值,设置:models.SET(值)
  12. b. 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象)
  13.  
  14. def func():
  15. return 10
  16.  
  17. class MyModel(models.Model):
  18. user = models.ForeignKey(
  19. to="User",
  20. to_field="id"
  21. on_delete=models.SET(func),)
  22. related_name=None, # 反向操作时,使用的字段名,用于代替 【表名_set】 如: obj.表名_set.all()
  23. related_query_name=None, # 反向操作时,使用的连接前缀,用于替换【表名】 如: models.UserGroup.objects.filter(表名__字段名=1).values('表名__字段名')
  24. limit_choices_to=None, # 在Admin或ModelForm中显示关联数据时,提供的条件:
  25. # 如:
  26. - limit_choices_to={'nid__gt': 5}
  27. - limit_choices_to=lambda : {'nid__gt': 5}
  28.  
  29. from django.db.models import Q
  30. - limit_choices_to=Q(nid__gt=10)
  31. - limit_choices_to=Q(nid=8) | Q(nid__gt=10)
  32. - limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
  33. db_constraint=True # 是否在数据库中创建外键约束
  34. parent_link=False # 在Admin中是否显示关联数据
  35.  
  36. OneToOneField(ForeignKey)
  37. to, # 要进行关联的表名
  38. to_field=None # 要关联的表中的字段名称
  39. on_delete=None, # 当删除关联表中的数据时,当前表与其关联的行的行为
  40.  
  41. ###### 对于一对一 ######
  42. # 1. 一对一其实就是 一对多 + 唯一索引
  43. # 2.当两个类之间有继承关系时,默认会创建一个一对一字段
  44. # 如下会在A表中额外增加一个c_ptr_id列且唯一:
  45. class C(models.Model):
  46. nid = models.AutoField(primary_key=True)
  47. part = models.CharField(max_length=12)
  48.  
  49. class A(C):
  50. id = models.AutoField(primary_key=True)
  51. code = models.CharField(max_length=1)
  52.  
  53. ManyToManyField(RelatedField)
  54. to, # 要进行关联的表名
  55. related_name=None, # 反向操作时,使用的字段名,用于代替 【表名_set】 如: obj.表名_set.all()
  56. related_query_name=None, # 反向操作时,使用的连接前缀,用于替换【表名】 如: models.UserGroup.objects.filter(表名__字段名=1).values('表名__字段名')
  57. limit_choices_to=None, # 在Admin或ModelForm中显示关联数据时,提供的条件:
  58. # 如:
  59. - limit_choices_to={'nid__gt': 5}
  60. - limit_choices_to=lambda : {'nid__gt': 5}
  61.  
  62. from django.db.models import Q
  63. - limit_choices_to=Q(nid__gt=10)
  64. - limit_choices_to=Q(nid=8) | Q(nid__gt=10)
  65. - limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
  66. symmetrical=None, # 仅用于多对多自关联时,symmetrical用于指定内部是否创建反向操作的字段
  67. # 做如下操作时,不同的symmetrical会有不同的可选字段
  68. models.BB.objects.filter(...)
  69.  
  70. # 可选字段有:code, id, m1
  71. class BB(models.Model):
  72.  
  73. code = models.CharField(max_length=12)
  74. m1 = models.ManyToManyField('self',symmetrical=True)
  75.  
  76. # 可选字段有: bb, code, id, m1
  77. class BB(models.Model):
  78.  
  79. code = models.CharField(max_length=12)
  80. m1 = models.ManyToManyField('self',symmetrical=False)
  81.  
  82. through=None, # 自定义第三张表时,使用字段用于指定关系表
  83. through_fields=None, # 自定义第三张表时,使用字段用于指定关系表中那些字段做多对多关系表
  84. from django.db import models
  85.  
  86. class Person(models.Model):
  87. name = models.CharField(max_length=50)
  88.  
  89. class Group(models.Model):
  90. name = models.CharField(max_length=128)
  91. members = models.ManyToManyField(
  92. Person,
  93. through='Membership',
  94. through_fields=('group', 'person'),
  95. )
  96.  
  97. class Membership(models.Model):
  98. group = models.ForeignKey(Group, on_delete=models.CASCADE)
  99. person = models.ForeignKey(Person, on_delete=models.CASCADE)
  100. inviter = models.ForeignKey(
  101. Person,
  102. on_delete=models.CASCADE,
  103. related_name="membership_invites",
  104. )
  105. invite_reason = models.CharField(max_length=64)
  106. db_constraint=True, # 是否在数据库中创建外键约束
  107. db_table=None, # 默认创建第三张表时,数据库中表的名称

多表关系以及参数

十四、MVC,MTV

  1. models(数据库,模型) viewshtml模板) controllers(业务逻辑处理) --> MVC
  2.  
  3. models(数据库,模型) templates(html模板) views(业务逻辑处理) --> MTV
  4.  
  5. Django -----基于-----> MTV

十五、事务

示例一:

  1. try:
  2. from django.db import transaction
  3. with transaction.atomic():
  4. models.UpDown.objects.create(user_id=user_id,article_id=article_id,up=False)
  5. models.Article.objects.filter(nid=article_id).update(down_count=F('down_count')+1)
  6. except Exception as e:
  7. response['status'] = False
  8. response['msg'] = str(e)

示例二:

  1. #函数里面有数据库操作,加在函数上
  2. from django.db.transaction import atomic
  3.  
  4. @atomic
  5. def cmd(self):
  6. model.....
  7. model.....

十六、随机生成验证码

  1. # import random
  2. # print(random.random()) #0-1的小数
  3. # print(random.randint(1,3)) #包括1和3
  4. # print("--",random.randrange(1,3)) #不包括1和3
  5.  
  6. #随机生成四位验证码
  7. import random
  8. checkcode = ''
  9. for i in range(4):
  10. current = random.randrange(0,4)
  11. if current != i:
  12. temp = chr(random.randint(65,90))
  13. else:
  14. temp = random.randint(0,9)
  15. checkcode += str(temp)
  16. print(checkcode)
  17. #KS3G
  18.  
  19. #随机生成8位验证码
  20. import string
  21.  
  22. print(string.ascii_lowercase)
  23. #abcdefghijklmnopqrstuvwxyz
  24. print(string.digits)
  25. #
  26.  
  27. obj = random.sample(string.ascii_lowercase+string.digits,8)
  28. print(obj)
  29. #['i', 'm', 'o', '9', '6', 'p', 'g', '0']
  30. row = "".join(random.sample(string.ascii_lowercase+string.digits,8))
  31. print(row)
  32. #417x6kyt

十七、AEC(高级加密)

  1. #3.6安装 pip3 install pycryptodome
  2. #mac pip3 install pycrypto

示例:

  1. ############################### 加密 ##############################
  2.  
  3. from Crypto.Cipher import AES
  4. def encrypt(message):
  5. key = b'dfdsdfsasdfdsdfs' #key必须是16的整数倍
  6. cipher = AES.new(key, AES.MODE_CBC, key) #创建对象
  7. ----------------------------------------------
  8. #先转成字节,把数据拼够16字节的整数倍
  9. ba_data = bytearray(message,encoding='utf-8') #把数据转成bytearray(byte的数组),bytearray只能追加数字,默认把数字转成字节
  10. v1 = len(ba_data)
  11. v2 = v1 % 16
  12. if v2 == 0:
  13. v3 = 16
  14. else:
  15. v3 = 16 - v2 #v3是追加的长度
  16. for i in range(v3):
  17. ba_data.append(v3) #bytearray只能追加数字,默认把数字转成字节
  18. final_data = ba_data.decode('utf-8')
  19. ----------------------------------------------
  20. msg = cipher.encrypt(final_data) #要加密的字符串,必须是16个字节或16个字节的倍数,加密后是byte格式
  21. return msg
  22.  
  23. ############################### 解密 ##############################
  24. def decrypt(msg):
  25. key = b'dfdsdfsasdfdsdfs'
  26. cipher = AES.new(key, AES.MODE_CBC, key)
  27. result = cipher.decrypt(msg) #把加密后的字节解密成不加密的字节
  28. data = result[0:-result[-1]]
  29. return str(data,encoding='utf-8')

十八、前端Format方法

为字符串创建Format方法,用于字符串格式化

  1. String.prototype.Format=function (arg) {
  2. //console.log(this,arg); //this,当前调用方法的字符串,arg为Format方法传入的参数
  3. //return ''; //return,格式化之后获取的新内容,return啥就替换为啥
  4. var temp = this.replace(/\{(\w+)\}/g,function (k,kk) {
  5. // k相当于{(\w+)},kk相当于(\w+)要替换的东西,arg一般是一个字典
  6. return arg[kk];
  7. });
  8. return temp;
  9. };
  10.  
  11. #调用
  12. a = {nid}
  13. b = {"nid":""}
  14. a.Format(b)

十九、高级使用----反射

  1. 反射:
  2. getattr(obj,'xxx')
  3.  
  4. 导入模块:
  5. import re
  6. 'django.middleware.clickjacking.XFrameOptionsMiddleware'
  7. m = importlib.import_module('django.middleware.clickjacking')
  8. cls = getattr(m,'XFrameOptionsMiddleware')
  9. cls()
  10.  
  11. 面向对象:
  12.  
  13. #示例一: 之后爬虫使用
  14. class Foo:
  15. def __init__(self):
  16. pass
  17.  
  18. @classmethod
  19. def instance(cls):
  20. return cls()
  21.  
  22. def process(self):
  23. pass
  24.  
  25. if hasattr(Foo,'instance'):
  26. obj = Foo.instance()
  27. else:
  28. obj = Foo()
  29. obj.process()
  30.  
  31. #示例二:
  32. class A:
  33. def f1(self):
  34. self.f2()
  35.  
  36. def f2(self):
  37. print('A.f2')
  38.  
  39. class B(A):
  40. def f2(self):
  41. print("B.f2")
  42.  
  43. obj = B()
  44. obj.f1()

二十、request

1 客户端向服务端发送多层字典的值

  1. obj = {
  2. 'data':{
  3. "k1":"v1",
  4. "k2":"v2"
  5. },
  6. 'status': True
  7. }
  8.  
  9. #json发送
  10. requests.post("http://www.baidu.com",json=obj)
  11.  
  12. #发送数据内部默认处理(会在内部把字典obj json.dumps序列成字符串,发送给服务端)
  13.  
  14. #body: json.dumps(obj)
  15. #headers= {'content-type':'application/json'} #默认加入
  16.  
  17. #只有设置如下请求头request.post才能接受,但不能接受多层字典的数据,接受第二层字典只能接受key,不能接受value
  18. #headers= {'content-type':"application/x-www-form-urlencoded"}
  19.  
  20. #接受上面格式发送的数据
  21. if request.method == 'POST':
  22. obj = json.loads(request.body.decode('utf-8'))

2 request.post 和request.body

  1. #接受
  2. requests.boby
  3. - 请求体原生的值
  4.  
  5. requests.POST
  6. - 根据特殊的请求头从requests.boby获取数据,不能接受多层字典的数据

3 三者相等

  1. #方式一:
  2.  
  3. requests.post("http://www.baidu.com",json=obj)
  4.  
  5. #方式二:
  6.  
  7. requests.post(
  8. url="http://www.baidu.com",
  9. headers={'content-type':'application/json'},
  10. data=json.dumps(obj)
  11. )
  12.  
  13. #方式三():
  14.  
  15. requests.post(
  16. url="http://www.baidu.com",
  17. headers={'content-type':'application/json'},
  18. data=bytes(json.dumps(obj),encoding="utf-8")
  19. )

二十一、hashlib加密(md5)

md5加密

  1. m = hashlib.md5()
  2. m.update(bytes(new_key,encoding='utf-8')) #里面是字节数据
  3. md5_key = m.hexdigest() #返回值是字符窜类型

二十二、命令行执行Django脚本

  1. - #效仿manage.py加入的环境变量在脚本的文件加入
  2. - #手动注册django所有的APP  
  1. import sys,os
  2. -----------------------举例
  3. from audit.backend import user_interactive
  4.  
  5. if __name__ == "__main__":
  6. os.environ.setdefault("DJANGO_SETTINGS_MODULE", "LuffyAudit.settings")
  7. import django
  8. django.setup() #手动注册django所有的APP
  9. -----------------------举例
  10. obj = user_interactive.UserShell(sys.argv)
  11. obj.start()

二十三、API验证

  1. API验证:
  2. a. 发令牌: 静态
  3. PS: 隐患 key被别人获取
  4. b. 动态令牌
  5. PS: (问题越严重)用户生成的每个令牌被黑客获取到,都会破解
  6. c. 高级版本
  7. PS: 黑客网速快,会窃取, so要对数据加密
  8. d. 终极版本
  9.  
  10. 特点:
  11. 为什么要用API
  12. - 数据在传输过程中,保证数据安全
  13. 你是如何设计的
  14. - Tornado 中的加密Cookie类似
  15. - 创建动态key md5(key + time)|time (Tornado中也是这么做)
  16. - 限制
  17. - 第一关: 时间
  18. - 第二关: 算法规则
  19. - 第三关: 已访问的记录
  20. PS: 黑客网速快,会窃取, so要对数据加密

1 客户端和服务端都有一个相同的key

  1. 客户端把key发给服务端,服务端拿着自己的key和客户端的key做比较
  2.  
  3. ###客户端
  4.  
  5. import time
  6. import requests
  7.  
  8. key = "asdfasdfasdfasdf098712sdfs"
  9.  
  10. response = requests.get("http://127.0.0.1:8000/api/asset.html",headers={'OpenKey':key})
  11. print(response.text)
  12.  
  13. ###服务端
  14.  
  15. #print(request.META)
  16. key = request.META.get("HTTP_OPENKEY")
  17. if key != settings.AUTH_KEY:
  18. return HttpResponse("验证失败")

2 key和时间

  1. #客户端和服务端都有一个相同的key
  2. #客户端把加密key和当前时间发给服务端,服务端收到后把客户端发来的时间和自己的key加密
  3. #然后把加密后的字串和客户端的字串比较
  4.  
  5. #客户端
  6.  
  7. import time
  8. import requests
  9. import hashlib
  10.  
  11. ctime = time.time()
  12. key = "asdfasdfasdfasdf098712sdfs"
  13. new_key = "%s|%s" %(key,ctime,)
  14.  
  15. m = hashlib.md5()
  16. m.update(bytes(new_key,encoding='utf-8')) #里面是字节数据
  17. md5_key = m.hexdigest() #返回值是字符串类型
  18.  
  19. md5_time_key = "%s|%s" %(md5_key,ctime)
  20.  
  21. response = requests.get("http://127.0.0.1:8000/api/asset.html",headers={'OpenKey':md5_time_key})
  22. print(response.text)
  23.  
  24. #服务端
  25. client_md5_time_key = request.META.get("HTTP_OPENKEY")
  26.  
  27. client_md5_key,client_ctime = client_md5_time_key.split("|")
  28.  
  29. temp = "%s|%s"%(settings.AUTH_KEY,client_ctime)
  30. m = hashlib.md5()
  31. m.update(bytes(temp, encoding='utf-8'))
  32. server_md5_key = m.hexdigest()
  33.  
  34. if server_md5_key != client_md5_key:
  35. return HttpResponse("验证失败")

3 高级版本

  1. #客户端和服务端都有一个相同的key
  2. #客户端把加密key和当前时间发给服务端
  3. #服务端验证:
  4. #1)服务端判断服务器当前的时间是否比客户端时间快10s,如果在10s内通过,有效的杜绝了案例二成千上万的key
  5. #2)服务器获取客户端时间和自己key加密然后和 客户端获取到的key比较
  6. #3)删除与现在时间相差10s的数据(之后用memcache,redis)
  7. #3)在字典里判断是否有这个key,如果有不通过,没有加入字典(之后用memcache,redis)
  8.  
  9. #客户端
  10. import time
  11. import requests
  12. import hashlib
  13.  
  14. ctime = time.time()
  15. key = "asdfasdfasdfasdf098712sdfs"
  16. new_key = "%s|%s" %(key,ctime,)
  17.  
  18. m = hashlib.md5()
  19. m.update(bytes(new_key,encoding='utf-8')) #里面是字节数据
  20. md5_key = m.hexdigest() #返回值是字符串类型
  21.  
  22. md5_time_key = "%s|%s" %(md5_key,ctime)
  23.  
  24. print(md5_time_key)
  25. response = requests.get("http://127.0.0.1:8000/api/asset.html",headers={'OpenKey':md5_time_key})
  26.  
  27. #黑客获取调用
  28. #response = requests.get("http://127.0.0.1:8000/api/asset.html",headers={'OpenKey':"f610077a7001c53b5a74868c5544b388|1501514254.455578"})
  29. print(response.text)
  30.  
  31. #服务端
  32. api_key_record ={
  33. "76942d662d98ebe3b920a7b791bf5040|1501510243.92804":1501510243.92804,
  34. }
  35.  
  36. def asset(request):
  37.  
  38. client_md5_time_key = request.META.get("HTTP_OPENKEY")
  39.  
  40. client_md5_key,client_ctime = client_md5_time_key.split("|")
  41. client_ctime = float(client_ctime)
  42. server_ctime = time.time()
  43.  
  44. #第一关 时间关
  45. if server_ctime - client_ctime > 10:
  46. return HttpResponse("第一关 小伙子,别虎我,太长了")
  47.  
  48. #第二关 客户端时间和服务端key加密和 客户端的密钥对比
  49. temp = "%s|%s"%(settings.AUTH_KEY,client_ctime)
  50. m = hashlib.md5()
  51. m.update(bytes(temp, encoding='utf-8'))
  52. server_md5_key = m.hexdigest()
  53. if server_md5_key != client_md5_key:
  54. return HttpResponse("第二关 规则正确")
  55.  
  56. #以后基于memcache,目前先写入内存删除超过10s的值
  57. for k in list(api_key_record.keys()):
  58. v = api_key_record[k]
  59. if server_ctime > v:
  60. del api_key_record[k]
  61.  
  62. #第三关 判断字典里是否有之前访问的key,如果有不通过,没有加入字典
  63. if client_md5_time_key in api_key_record:
  64. return HttpResponse("第三关 已经有人来过了")
  65. else:
  66. api_key_record[client_md5_time_key] = client_ctime + 10

4 终极版本

  1. 注意: key 是从配置文件获取的
  2.  
  3. 装饰器要返回Httpresponse对象
  1. __author__ = 'Administrator'
  2. from Crypto.Cipher import AES
  3. from lib.conf.config import settings
  4. def encrypt(message):
  5. """
  6. 数据加密
  7. :param message:
  8. :return:
  9. """
  10. key = settings.DATA_KEY
  11. cipher = AES.new(key, AES.MODE_CBC, key)
  12. ba_data = bytearray(message,encoding='utf-8')
  13. v1 = len(ba_data)
  14. v2 = v1 % 16
  15. if v2 == 0:
  16. v3 = 16
  17. else:
  18. v3 = 16 - v2
  19. for i in range(v3):
  20. ba_data.append(v3)
  21. final_data = ba_data.decode('utf-8')
  22. msg = cipher.encrypt(final_data) # 要加密的字符串,必须是16个字节或16个字节的倍数
  23. return msg
  24.  
  25. def decrypt(msg):
  26. """
  27. 数据解密
  28. :param message:
  29. :return:
  30. """
  31. from Crypto.Cipher import AES
  32. key = settings.DATA_KEY
  33. cipher = AES.new(key, AES.MODE_CBC, key)
  34. result = cipher.decrypt(msg) # result = b'\xe8\xa6\x81\xe5\x8a\xa0\xe5\xaf\x86\xe5\x8a\xa0\xe5\xaf\x86\xe5\x8a\xa0sdfsd\t\t\t\t\t\t\t\t\t'
  35. data = result[0:-result[-1]]
  36. return str(data,encoding='utf-8')
  37.  
  38. def auth():
  39. """
  40. API验证
  41. :return:
  42. """
  43. import time
  44. import requests
  45. import hashlib
  46.  
  47. ctime = time.time()
  48. key = "asdfasdfasdfasdf098712sdfs"
  49. new_key = "%s|%s" %(key,ctime,)
  50.  
  51. m = hashlib.md5()
  52. m.update(bytes(new_key,encoding='utf-8')) #里面是字节数据
  53. md5_key = m.hexdigest() #返回值是字符窜类型
  54.  
  55. md5_time_key = "%s|%s" %(md5_key,ctime)
  56.  
  57. return md5_time_key

lib/utils.py

  1. from Crypto.Cipher import AES
  2. import requests
  3. import json
  4. from lib.utils import encrypt
  5. from lib.utils import auth
  6.  
  7. #对数据加密字典
  8. v1 = encrypt(json.dumps({"k1":"v1"})) #获取的是加密后的字节
  9. print(v1)
  10.  
  11. response = requests.post(
  12. url="http://127.0.0.1:8000/api/asset.html",
  13. headers={'OpenKey':auth(),'content-type':'application/json'},
  14. data=v1
  15. )
  16.  
  17. print(response.text)

客户端调用

  1. import json
  2. import hashlib
  3. from django.shortcuts import render,HttpResponse
  4. from repository import models
  5. from django.conf import settings
  6. from api.service import PluginManager
  7. import time
  8. import json
  9. from Crypto.Cipher import AES
  10.  
  11. api_key_record ={
  12. "76942d662d98ebe3b920a7b791bf5040|1501510243.92804":1501510243.92804,
  13. }
  14.  
  15. def decrypt(msg):
  16. key = b'dfdsdfsasdfdsdfs'
  17. cipher = AES.new(key, AES.MODE_CBC, key)
  18. result = cipher.decrypt(msg) # 把加密后的字节解密成不加密的字节
  19. data = result[0:-result[-1]]
  20. return str(data, encoding='utf-8')
  21.  
  22. def outer(func):
  23. def wrapper(request):
  24. client_md5_time_key = request.META.get("HTTP_OPENKEY")
  25.  
  26. client_md5_key, client_ctime = client_md5_time_key.split("|")
  27. client_ctime = float(client_ctime)
  28. server_ctime = time.time()
  29.  
  30. # 第一关 时间关
  31. if server_ctime - client_ctime > 30:
  32. return HttpResponse("第一关 小伙子,别虎我,太长了")
  33.  
  34. # 第二关 客户端时间和服务端key加密和 客户端的密钥对比
  35. temp = "%s|%s" % (settings.AUTH_KEY, client_ctime)
  36. m = hashlib.md5()
  37. m.update(bytes(temp, encoding='utf-8'))
  38. server_md5_key = m.hexdigest()
  39. if server_md5_key != client_md5_key:
  40. return HttpResponse("第二关 规则正确")
  41.  
  42. # 以后基于memcache,目前先写入内存删除超过10s的值
  43. for k in list(api_key_record.keys()):
  44. v = api_key_record[k]
  45. if server_ctime > v:
  46. del api_key_record[k]
  47.  
  48. # 第三关 判断字典里是否有之前访问的key,如果有不通过,没有加入字典
  49. if client_md5_time_key in api_key_record:
  50. return HttpResponse("第三关 已经有人来过了")
  51. else:
  52. api_key_record[client_md5_time_key] = client_ctime + 10
  53. obj = func(request)
  54. return obj
  55.  
  56. return wrapper
  57.  
  58. @outer
  59. def asset(request):
  60.  
  61. if request.method == 'GET':
  62. ys = '重要的不能被闲杂人等看的数据'
  63. return HttpResponse(ys)
  64.  
  65. elif request.method == 'POST':
  66.  
  67. server_info = decrypt(request.body)
  68. server_info = json.loads(server_info)
  69.  
  70. # # 新资产信息
  71. # server_info = json.loads(request.body.decode('utf-8'))
  72. hostname = server_info['basic']['data']['hostname']
  73. # 老资产信息
  74. server_obj = models.Server.objects.filter(hostname=hostname).first()
  75. if not server_obj:
  76. return HttpResponse('当前主机名在资产中未录入')
  77.  
  78. PluginManager(server_info,server_obj,hostname).exec_plugin()
  79.  
  80. return HttpResponse("...")

服务端代码

二十四、KindEditor

1 进入官网

2 下载

官网下载:http://kindeditor.net/down.php

3 文件夹说明

  1. ├── asp asp示例
  2. ├── asp.net asp.net示例
  3. ├── attached 空文件夹,放置关联文件attached
  4. ├── examples HTML示例
  5. ├── jsp java示例
  6. ├── kindeditor-all-min.js 全部JS(压缩)
  7. ├── kindeditor-all.js 全部JS(未压缩)
  8. ├── kindeditor-min.js KindEditor JS(压缩)
  9. ├── kindeditor.js KindEditor JS(未压缩)
  10. ├── lang 支持语言
  11. ├── license.txt License
  12. ├── php PHP示例
  13. ├── plugins KindEditor内部使用的插件
  14. └── themes KindEditor主题

4 基本使用

  1. <textarea name="content" id="content"></textarea>
  2.  
  3. <script src="/static/jquery-1.12.4.js"></script>
  4. <script src="/static/plugins/kind-editor/kindeditor-all.js"></script>
  5. <script>
  6. $(function () {
  7. initKindEditor();
  8. });
  9.  
  10. function initKindEditor() {
  11. var kind = KindEditor.create('#content', {
  12. width: '100%', // 文本框宽度(可以百分比或像素)
  13. height: '300px', // 文本框高度(只能像素)
  14. minWidth: 200, // 最小宽度(数字)
  15. minHeight: 400 // 最小高度(数字)
  16. });
  17. }
  18. </script>

5 详细参数

http://kindeditor.net/docs/option.html

6 上传文件示例

  1. <!DOCTYPE html>
  2. <html>
  3. <head lang="en">
  4. <meta charset="UTF-8">
  5. <title></title>
  6. </head>
  7. <body>
  8.  
  9. <div>
  10. <h1>文章内容</h1>
  11. {{ request.POST.content|safe }}
  12. </div>
  13.  
  14. <form method="POST">
  15. <h1>请输入内容:</h1>
  16. {% csrf_token %}
  17. <div style="width: 500px; margin: 0 auto;">
  18. <textarea name="content" id="content"></textarea>
  19. </div>
  20. <input type="submit" value="提交"/>
  21. </form>
  22.  
  23. <script src="/static/jquery-1.12.4.js"></script>
  24. <script src="/static/plugins/kind-editor/kindeditor-all.js"></script>
  25. <script>
  26. $(function () {
  27. initKindEditor();
  28. });
  29.  
  30. function initKindEditor() {
  31. var a = 'kind';
  32. var kind = KindEditor.create('#content', {
  33. width: '100%', // 文本框宽度(可以百分比或像素)
  34. height: '300px', // 文本框高度(只能像素)
  35. minWidth: 200, // 最小宽度(数字)
  36. minHeight: 400, // 最小高度(数字)
  37. uploadJson: '/kind/upload_img/',
  38. extraFileUploadParams: {
  39. 'csrfmiddlewaretoken': '{{ csrf_token }}'
  40. },
  41. fileManagerJson: '/kind/file_manager/',
  42. allowPreviewEmoticons: true,
  43. allowImageUpload: true
  44. });
  45. }
  46. </script>
  47. </body>
  48. </html>

HTML

  1. import os
  2. import json
  3. import time
  4.  
  5. from django.shortcuts import render
  6. from django.shortcuts import HttpResponse
  7.  
  8. def index(request):
  9. """
  10. 首页
  11. :param request:
  12. :return:
  13. """
  14. return render(request, 'index.html')
  15.  
  16. def upload_img(request):
  17. """
  18. 文件上传
  19. :param request:
  20. :return:
  21. """
  22. dic = {
  23. 'error': 0,
  24. 'url': '/static/imgs/20130809170025.png',
  25. 'message': '错误了...'
  26. }
  27.  
  28. return HttpResponse(json.dumps(dic))
  29.  
  30. def file_manager(request):
  31. """
  32. 文件管理
  33. :param request:
  34. :return:
  35. """
  36. dic = {}
  37. root_path = '/Users/wupeiqi/PycharmProjects/editors/static/'
  38. static_root_path = '/static/'
  39. request_path = request.GET.get('path')
  40. if request_path:
  41. abs_current_dir_path = os.path.join(root_path, request_path)
  42. move_up_dir_path = os.path.dirname(request_path.rstrip('/'))
  43. dic['moveup_dir_path'] = move_up_dir_path + '/' if move_up_dir_path else move_up_dir_path
  44.  
  45. else:
  46. abs_current_dir_path = root_path
  47. dic['moveup_dir_path'] = ''
  48.  
  49. dic['current_dir_path'] = request_path
  50. dic['current_url'] = os.path.join(static_root_path, request_path)
  51.  
  52. file_list = []
  53. for item in os.listdir(abs_current_dir_path):
  54. abs_item_path = os.path.join(abs_current_dir_path, item)
  55. a, exts = os.path.splitext(item)
  56. is_dir = os.path.isdir(abs_item_path)
  57. if is_dir:
  58. temp = {
  59. 'is_dir': True,
  60. 'has_file': True,
  61. 'filesize': 0,
  62. 'dir_path': '',
  63. 'is_photo': False,
  64. 'filetype': '',
  65. 'filename': item,
  66. 'datetime': time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(os.path.getctime(abs_item_path)))
  67. }
  68. else:
  69. temp = {
  70. 'is_dir': False,
  71. 'has_file': False,
  72. 'filesize': os.stat(abs_item_path).st_size,
  73. 'dir_path': '',
  74. 'is_photo': True if exts.lower() in ['.jpg', '.png', '.jpeg'] else False,
  75. 'filetype': exts.lower().strip('.'),
  76. 'filename': item,
  77. 'datetime': time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(os.path.getctime(abs_item_path)))
  78. }
  79.  
  80. file_list.append(temp)
  81. dic['file_list'] = file_list
  82. return HttpResponse(json.dumps(dic))

views

7 XSS过滤特殊标签

处理依赖

  1. pip3 install beautifulsoup4
  1. from bs4 import BeautifulSoup
  2.  
  3. class XSSFilter(object):
  4. __instance = None
  5.  
  6. def __init__(self):
  7. # XSS白名单
  8. self.valid_tags = {
  9. "font": ['color', 'size', 'face', 'style'],
  10. 'b': [],
  11. 'div': [],
  12. "span": [],
  13. "table": [
  14. 'border', 'cellspacing', 'cellpadding'
  15. ],
  16. 'th': [
  17. 'colspan', 'rowspan'
  18. ],
  19. 'td': [
  20. 'colspan', 'rowspan'
  21. ],
  22. "a": ['href', 'target', 'name'],
  23. "img": ['src', 'alt', 'title'],
  24. 'p': [
  25. 'align'
  26. ],
  27. "pre": ['class'],
  28. "hr": ['class'],
  29. 'strong': []
  30. }
  31.  
  32. @classmethod
  33. def instance(cls):
  34. if not cls.__instance:
  35. obj = cls()
  36. cls.__instance = obj
  37. return cls.__instance
  38.  
  39. def process(self, content):
  40. soup = BeautifulSoup(content, 'lxml')
  41. # 遍历所有HTML标签
  42. for tag in soup.find_all(recursive=True):
  43. # 判断标签名是否在白名单中
  44. if tag.name not in self.valid_tags:
  45. tag.hidden = True
  46. if tag.name not in ['html', 'body']:
  47. tag.hidden = True
  48. tag.clear()
  49. continue
  50. # 当前标签的所有属性白名单
  51. attr_rules = self.valid_tags[tag.name]
  52. keys = list(tag.attrs.keys())
  53. for key in keys:
  54. if key not in attr_rules:
  55. del tag[key]
  56.  
  57. return soup.renderContents()
  58.  
  59. if __name__ == '__main__':
  60. html = """<p class="title">
  61. <b>The Dormouse's story</b>
  62. </p>
  63. <p class="story">
  64. <div name='root'>
  65. Once upon a time there were three little sisters; and their names were
  66. <a href="http://example.com/elsie" class="sister c1" style='color:red;background-color:green;' id="link1"><!-- Elsie --></a>
  67. <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
  68. <a href="http://example.com/tillie" class="sister" id="link3">Tilffffffffffffflie</a>;
  69. and they lived at the bottom of a well.
  70. <script>alert(123)</script>
  71. </div>
  72. </p>
  73. <p class="story">...</p>"""
  74.  
  75. v = XSSFilter.instance().process(html)
  76. print(v)

XSS示例

  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. from bs4 import BeautifulSoup
  4.  
  5. class XSSFilter(object):
  6. __instance = None
  7.  
  8. def __init__(self):
  9. # XSS白名单
  10. self.valid_tags = {
  11. "font": ['color', 'size', 'face', 'style'],
  12. 'b': [],
  13. 'div': [],
  14. "span": [],
  15. "table": [
  16. 'border', 'cellspacing', 'cellpadding'
  17. ],
  18. 'th': [
  19. 'colspan', 'rowspan'
  20. ],
  21. 'td': [
  22. 'colspan', 'rowspan'
  23. ],
  24. "a": ['href', 'target', 'name'],
  25. "img": ['src', 'alt', 'title'],
  26. 'p': [
  27. 'align'
  28. ],
  29. "pre": ['class'],
  30. "hr": ['class'],
  31. 'strong': []
  32. }
  33.  
  34. def __new__(cls, *args, **kwargs):
  35. """
  36. 单例模式
  37. :param cls:
  38. :param args:
  39. :param kwargs:
  40. :return:
  41. """
  42. if not cls.__instance:
  43. obj = object.__new__(cls, *args, **kwargs)
  44. cls.__instance = obj
  45. return cls.__instance
  46.  
  47. def process(self, content):
  48. soup = BeautifulSoup(content, 'lxml')
  49. # 遍历所有HTML标签
  50. for tag in soup.find_all(recursive=True):
  51. # 判断标签名是否在白名单中
  52. if tag.name not in self.valid_tags:
  53. tag.hidden = True
  54. if tag.name not in ['html', 'body']:
  55. tag.hidden = True
  56. tag.clear()
  57. continue
  58. # 当前标签的所有属性白名单
  59. attr_rules = self.valid_tags[tag.name]
  60. keys = list(tag.attrs.keys())
  61. for key in keys:
  62. if key not in attr_rules:
  63. del tag[key]
  64.  
  65. return soup.renderContents()
  66.  
  67. if __name__ == '__main__':
  68. html = """<p class="title">
  69. <b>The Dormouse's story</b>
  70. </p>
  71. <p class="story">
  72. <div name='root'>
  73. Once upon a time there were three little sisters; and their names were
  74. <a href="http://example.com/elsie" class="sister c1" style='color:red;background-color:green;' id="link1"><!-- Elsie --></a>
  75. <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
  76. <a href="http://example.com/tillie" class="sister" id="link3">Tilffffffffffffflie</a>;
  77. and they lived at the bottom of a well.
  78. <script>alert(123)</script>
  79. </div>
  80. </p>
  81. <p class="story">...</p>"""
  82.  
  83. obj = XSSFilter()
  84. v = obj.process(html)
  85. print(v)

基于__new__实现单例模式示例

8 示例图

二十五、Django多级评论

1 原理

  1. #多级评论原理简单原理,弄完之后发现基础白学了
  2. msg_list = [
  3. {'id':1,'content':'xxx','parent_id':None},
  4. {'id':2,'content':'xxx','parent_id':None},
  5. {'id':3,'content':'xxx','parent_id':None},
  6. {'id':4,'content':'xxx','parent_id':1},
  7. {'id':5,'content':'xxx','parent_id':4},
  8. {'id':6,'content':'xxx','parent_id':2},
  9. {'id':7,'content':'xxx','parent_id':5},
  10. {'id':8,'content':'xxx','parent_id':3},
  11. ]
  12. #python里面的apend之类的东西都是引用的原来数据的内从地址,对原数据进行操作的话
  13. #我们引用的数据也会发生一样的变化(字典列表之类的)
  14.  
  15. #骗子的方法
  16. # for i in msg_list:
  17. # i['child']=[]
  18. # for i in range(len(msg_list)-1,-1,-1):
  19. # if msg_list[i]['parent_id']:
  20. # msg_list[msg_list[i]['parent_id'] - 1]['child'].append(msg_list[i])
  21. # new_msg_list = [i for i in msg_list if i['parent_id'] is None]
  22. # print(new_msg_list)
  23.  
  24. #老师讲的方法
  25. # v=[row.setdefault('child',[]) for row in msg_list] #这和地下的第一个for循环的作用是一样的,给每一个元素加一个'child':[]
  26. # print(msg_list)
  27. #如果我们想加快索引(快点找到数据的话)就建一个字典的数据结构
  28. msg_list_dict={} #加快索引,节省时间
  29. for item in msg_list:
  30. item['child']=[]
  31. msg_list_dict[item['id']]=item #字典中key为item['id'],value为item
  32. #把字典数据结构填上数据,能够加快索引,而且我们数据还是占得原来的内从空间
  33. #我们只是引用了数据的内容空间,所以不存在新的数据结构浪费空间一说
  34. result=[]
  35. for item in msg_list:
  36. pid=item['parent_id']
  37. if pid: #如果parent_id不为空,说明它是子级,要把自己加入对应的父级
  38. msg_list_dict[pid]['child'].append(item)
  39. else: #如果为空,说明他是父级,要把它单独领出来用
  40. result.append(item)
  41. #result就是我们最终要的结果,因为这里面全是引用,所有数据的内存地址都没有变
  42. #只不过被多个数据结构引用了而已
  43. print(result)

2 精简版

  1. def comments(request,nid):
  2. res={'status':True,'data':None,'msg':None}
  3. try:
  4. comment_list = models.Comment.objects.filter(article_id=nid).values()
  5. com_list = list(comment_list) # 所有的评论,列表套字典
  6. com_list_dict = {} # 建立一个方便查找的数据结构字典
  7. for item in com_list: # 循环评论列表,给每一条评论加一个child:[]就是让他装对他回复的内容
  8. item['create_time'] = str(item['create_time'])
  9. item['child'] = []
  10. com_list_dict[item['nid']] = item
  11. result = []
  12. for item in com_list:
  13. rid = item['reply_id']
  14. if rid: # 如果reply_id不为空的话,那么就是说明他是子评论,我们要把他加入对应的评论后面
  15. com_list_dict[rid]['child'].append(item)
  16. else:
  17. result.append(item)
  18. print(result)
  19. # comment_str = comment_tree(result)
  20. # 这是在服务器上递归完之后,然后在传到前端,但是这样会增加服务器压力
  21. #所以这种方式我们直接就不用了
  22. res['data']=result
  23. except Exception as e:
  24. res['status']=False
  25. res['mag']=str(e)
  26. return HttpResponse(json.dumps(res))

views

  1. <style>
  2. .comment{
  3. margin-left:20px;
  4. }
  5. </style>
  6.  
  7. <body>
  8. <div id="commentArea">
  9.  
  10. </div>
  11. </body>
  12. <script src="/static/jquery-3.2.1.js"></script>
  13. <script>
  14. //自定义JS中字符串格式化方法
  15. String.prototype.Format=function (arg) {
  16. //console.log(this,arg); //this,当前调用方法的字符串,arg为Format方法传入的参数
  17. //return '666'; //return,格式化之后获取的新内容,return啥就替换为啥
  18. var temp = this.replace(/\{(\w+)\}/g,function (k,kk) {
  19. // k相当于{(\w+)},kk相当于(\w+)要替换的东西,arg一般是一个字典
  20. return arg[kk];
  21. });
  22. return temp;
  23. };
  24.  
  25. $(function () {
  26. //发送Ajax请求,获取所有评论的信息
  27. //列表
  28. //JS生成结构
  29. var token=$.cookie('csrftoken');
  30. $.ajax({
  31. url:"/comments-{{ article_obj.nid }}.html",
  32. type:"GET",
  33. dataType:"JSON",
  34. success:function (arg) {
  35. if (arg.status){
  36. var comment=commentTree(arg.data);
  37. $('#commentArea').append(comment);
  38. }else{
  39. alert(arg.msg);
  40. }
  41. }
  42. })
  43. });
  44.  
  45. //多级评论递归函数,js函数里面也有return,自己写js字符串格式化
  46. //pyhton中字符串的方法都是str下的,js中是String.prototype下找的
  47. function commentTree(commentList) {
  48. var comment_str="<div class='comment'>";
  49. $.each(commentList,function (k,row) {
  50. var temp="<div class='content'>{content}</div>".Format({content:row.content});
  51. comment_str += temp;
  52. if (row.child.length>0){
  53. comment_str += commentTree(row.child);
  54. }
  55. });
  56. comment_str += '</div>';
  57. return comment_str
  58. }
  59. </script>

html

二十六、REST framework

1. 什么是REST

  • REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移”
  • REST从资源的角度类审视整个网络,它将分布在网络中某个节点的资源通过URL进行标识,客户端应用通过URL来获取资源的表征,获得这些表征致使这些应用转变状态
  • REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移”
  • 所有的数据,不过是通过网络获取的还是操作(增删改查)的数据,都是资源,将一切数据视为资源是REST区别与其他架构风格的最本质属性
  • 对于REST这种面向资源的架构风格,有人提出一种全新的结构理念,即:面向资源架构(ROA:Resource Oriented Architecture)

设计参考:http://www.ruanyifeng.com/blog/2014/05/restful_api.html

2. 目前如何实现 REST API ?

按照规则,根据不同的请求方式做出不同的处理,并且返回内容以及相应状态码

3. 什么是 Django REST framework

Django REST framework是一个基于Django开发的app,用于快速搭建REST API。

安装:

  1. pip3 install djangorestframework

a. 快速使用

  1. INSTALLED_APPS = [
  2. ...
  3. 'rest_framework',
  4. ]

1.注册APP

  1. from rest_framework import routers
  2. from . import views
  3.  
  4. router = routers.DefaultRouter()
  5. router.register(r'users', views.UserInfoViewSet)
  6.  
  7. urlpatterns = [
  8. url(r'^', include(router.urls)),
  9. ]

2.注册路由

  1. from rest_framework import viewsets
  2. from . import models
  3. from . import serializers
  4.  
  5. # ########### 1. 基本处理方式 ###########
  6.  
  7. class UserInfoViewSet(viewsets.ModelViewSet):
  8. """
  9. API endpoint that allows users to be viewed or edited.
  10. """
  11. queryset = models.UserInfo.objects.all().order_by('-id')
  12. serializer_class = serializers.UserInfoSerializer

3.编写ViewSet,视图函数

  1. from rest_framework import serializers
  2. from . import models
  3.  
  4. class UserInfoSerializer(serializers.HyperlinkedModelSerializer):
  5. class Meta:
  6. model = models.UserInfo
  7. # fields = ('id', 'username', 'pwd','ug') # fields = '__all__'
  8. exclude = ('ug',)
  9. depth = 1 # 0<=depth<=10

4.编写serializers,form验证以及数据库操作

PS:最终访问路径

  1. [GET] http://127.0.0.1:8000/api/users/
  2. [POST] http://127.0.0.1:8000/api/users/
  3. [GET] http://127.0.0.1:8000/api/users/7/
  4. [PUT] http://127.0.0.1:8000/api/users/7/
  5. [DELETE] http://127.0.0.1:8000/api/users/7/

b. 基于CBV

  1. from django.conf.urls import url,include
  2. from django.contrib import admin
  3. from . import views
  4.  
  5. urlpatterns = [
  6. url(r'^users/$', views.UserList.as_view()),
  7. url(r'^users/(?P<pk>[0-9]+)/$', views.UserDetail.as_view()),
  8. ]

1.URL

  1. from rest_framework.views import APIView
  2. from rest_framework.response import Response
  3. from rest_framework.request import Request
  4. from rest_framework.parsers import JSONParser
  5. from . import models
  6. from . import serializers
  7.  
  8. class UserList(APIView):
  9. def get(self, request, *args, **kwargs):
  10. user_list = models.UserInfo.objects.all()
  11. serializer = serializers.MySerializer(instance=user_list, many=True)
  12. return Response(serializer.data)
  13.  
  14. def post(self, request, *args, **kwargs):
  15. data = JSONParser().parse(request)
  16. serializer = serializers.MySerializer(data=data)
  17. if serializer.is_valid():
  18. # print(serializer.data)
  19. # print(serializer.errors)
  20. # print(serializer.validated_data)
  21. # 如果有instance,则执行update方法;否则,执行create
  22. serializer.save()
  23. return Response(serializer.data, status=201)
  24. return Response(serializer.errors, status=400)
  25.  
  26. class UserDetail(APIView):
  27. def get(self, request, *args, **kwargs):
  28. obj = models.UserInfo.objects.filter(pk=kwargs.get('pk')).first()
  29. serializer = serializers.MySerializer(obj)
  30. return Response(serializer.data)
  31.  
  32. def delete(self, request, *args, **kwargs):
  33. obj = models.UserInfo.objects.filter(pk=kwargs.get('pk')).first()
  34. obj.delete()
  35. return Response(status=204)
  36.  
  37. def put(self, request, *args, **kwargs):
  38. data = JSONParser().parse(request)
  39. obj = models.UserInfo.objects.filter(pk=kwargs.get('pk')).first()
  40. serializer = serializers.MySerializer(obj, data=data)
  41. if serializer.is_valid():
  42. serializer.save()
  43. return Response(serializer.data)
  44. return Response(serializer.errors, status=400)

2.编写视图函数

  1. from rest_framework import serializers
  2. from rest_framework.exceptions import ValidationError
  3. from . import models
  4.  
  5. class MySerializer(serializers.Serializer):
  6. id = serializers.IntegerField(read_only=True)
  7. username = serializers.CharField(required=False, allow_blank=True, max_length=100)
  8. pwd = serializers.CharField()
  9.  
  10. def validate_username(self, value):
  11. if value == '中国':
  12. raise ValidationError('用户名中存在敏感字符')
  13. return value
  14.  
  15. def validate_pwd(self, value):
  16. print(value)
  17. return value
  18.  
  19. def validate(self, attrs):
  20. print(attrs)
  21. return attrs
  22.  
  23. def create(self, validated_data):
  24. """
  25. 当执行save方法时,自动调用。instance未传值
  26. :param validated_data:
  27. :return:
  28. """
  29. print(validated_data)
  30. return models.UserInfo.objects.create(**validated_data)
  31.  
  32. def update(self, instance, validated_data):
  33. """
  34. 当执行save方法时,自动调用。instance传值
  35. :param instance:
  36. :param validated_data:
  37. :return:
  38. """
  39. instance.username = validated_data.get('username', instance.username)
  40. instance.save()
  41. return instance

3.编写serializers

c. 基于CBV

  1. from django.conf.urls import url,include
  2. from django.contrib import admin
  3. from . import views
  4.  
  5. urlpatterns = [
  6. url(r'^users/$', views.user_list),
  7. url(r'^users/(?P<pk>[0-9]+)/$', views.user_detail),
  8. ]

1.URL

  1. from django.http import JsonResponse,HttpResponse
  2. from rest_framework.response import Response
  3. from rest_framework.parsers import JSONParser
  4. from rest_framework.decorators import api_view
  5. from .serializers import MySerializer
  6. from . import models
  7.  
  8. @api_view(['GET',"POST"])
  9. def user_list(request):
  10. """
  11. List all code snippets, or create a new snippet.
  12. """
  13. if request.method == 'GET':
  14. user_list = models.UserInfo.objects.all()
  15. serializer = MySerializer(user_list,many=True)
  16. return Response(serializer.data)
  17.  
  18. elif request.method == 'POST':
  19. data = JSONParser().parse(request)
  20. serializer = MySerializer(data=data)
  21. if serializer.is_valid():
  22. print(serializer.data)
  23. print(serializer.errors)
  24. print(serializer.validated_data)
  25. # 如果有instance,则执行update方法;否则,执行create
  26. serializer.save()
  27. return Response(serializer.data, status=201)
  28. return Response(serializer.errors, status=400)
  29.  
  30. @api_view(['GET',"POST","PUT"])
  31. def user_detail(request, pk):
  32. """
  33. Retrieve, update or delete a code snippet.
  34. """
  35.  
  36. obj = models.UserInfo.objects.filter(pk=pk).first()
  37. if not obj:
  38. return HttpResponse(status=404)
  39.  
  40. if request.method == 'GET':
  41. serializer = MySerializer(obj)
  42. # return JsonResponse(serializer.data,json_dumps_params={'ensure_ascii':False},content_type='application/json;charset=utf-8')
  43. return Response(serializer.data)
  44.  
  45. elif request.method == 'PUT':
  46. data = JSONParser().parse(request)
  47. serializer = MySerializer(obj, data=data)
  48. if serializer.is_valid():
  49. serializer.save()
  50. return Response(serializer.data)
  51. return Response(serializer.errors, status=400)
  52.  
  53. elif request.method == 'DELETE':
  54. obj.delete()
  55. return Response(status=204)

2.视图函数

  1. from rest_framework import serializers
  2. from rest_framework.exceptions import ValidationError
  3. from . import models
  4.  
  5. class MySerializer(serializers.Serializer):
  6. id = serializers.IntegerField(read_only=True)
  7. username = serializers.CharField(required=False, allow_blank=True, max_length=100)
  8. pwd = serializers.CharField()
  9.  
  10. def validate_username(self, value):
  11. if value == '中国':
  12. raise ValidationError('用户名中存在敏感字符')
  13. return value
  14.  
  15. def validate_pwd(self, value):
  16. print(value)
  17. return value
  18.  
  19. def validate(self, attrs):
  20. print(attrs)
  21. return attrs
  22.  
  23. def create(self, validated_data):
  24. """
  25. 当执行save方法时,自动调用。instance未传值
  26. :param validated_data:
  27. :return:
  28. """
  29. print(validated_data)
  30. return models.UserInfo.objects.create(**validated_data)
  31.  
  32. def update(self, instance, validated_data):
  33. """
  34. 当执行save方法时,自动调用。instance传值
  35. :param instance:
  36. :param validated_data:
  37. :return:
  38. """
  39. instance.username = validated_data.get('username', instance.username)
  40. instance.save()
  41. return instance

3.编写serializers

d. 权限控制

  1. REST_FRAMEWORK = {
  2. 'DEFAULT_PERMISSION_CLASSES': [
  3. 'permissi.MyPermission',
  4. ]
  5. }

1.settings配置文件

  1. class MyPermission(object):
  2. """
  3. A base class from which all permission classes should inherit.
  4. """
  5.  
  6. def has_permission(self, request, view):
  7. """
  8. Return `True` if permission is granted, `False` otherwise.
  9. """
  10.  
  11. return True
  12.  
  13. def has_object_permission(self, request, view, obj):
  14. return True

2.权限控制

  1. - 全局配置
  2. Highcharts.setOptions({
  3. global: {
  4. useUTC: false
  5. }
  6. });
  7.  
  8. - 主配置
  9. var chart = new Highcharts.Chart('id1', {
  10. title: {
  11. text: '不同城市的月平均气温',
  12. x: 0
  13. },
  14. subtitle: {
  15. text: '数据来源: WorldClimate.com',
  16. x: 0
  17. },
  18. chart: {
  19. events: {
  20. load: function (e) {
  21. // 图标加载时,执行的函数
  22. }
  23. }
  24. },
  25. credits: {
  26. enable: true,
  27. position: {
  28. align: 'right',
  29. verticalAlign: 'bottom'
  30. },
  31. text: '老男孩',
  32. href: 'http://www.oldboyedu.com'
  33. },
  34. legend: {
  35. layout: 'vertical',
  36. align: 'right',
  37. verticalAlign: 'middle',
  38. borderWidth: 1
  39. },
  40.  
  41. xAxis: {
  42. // categories: ['1.1', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
  43. type: 'datetime',
  44. labels: {
  45. formatter: function () {
  46. return Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.value);
  47. },
  48. rotation: 30
  49. }
  50.  
  51. },
  52. yAxis: {
  53. title: {
  54. text: '数值'
  55. }
  56. },
  57. tooltip: {
  58. valueSuffix: '个',
  59. xDateFormat: "%Y-%m-%d %H:%M:%S",
  60. pointFormatter: function (e) {
  61. var tpl = '<span style="color:' + this.series.color + '">●</span> ' + this.series.name + ': <b>' + this.y + '</b><br/>';
  62. return tpl;
  63. },
  64. valueDecimals: 1,
  65. useHTML: true
  66. },
  67. plotOptions: {
  68. series: {
  69. cursor: 'pointer',
  70. events: {
  71. click: function (event) {
  72. // 点击某个指定点时,执行的事件
  73. console.log(this.name, event.point.x, event.point.y);
  74. }
  75. }
  76. }
  77. },
  78. series: [{
  79. name: '东京',
  80. // data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6]
  81. data: [
  82. [1501689804077.358, 8.0],
  83. [1501689814177.358, 6.9],
  84. [1501689824277.358, 16.9],
  85. [1501689834377.358, 11.9]
  86. ]
  87. },
  88. {
  89. name: '洛杉矶',
  90. // data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6]
  91. data: [
  92. [1501689804077.358, 18.0],
  93. [1501689814177.358, 16.9],
  94. [1501689824277.358, 26.9],
  95. [1501689834377.358, 9.9]
  96. ]
  97. }]
  98. });
  99.  
  100. // chart.addSeries({name:'北京',data: [216.4, 194.1, 95.6, 54.4, 29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5]});
  101. // 参数:数值;是否重绘; isShift; 是否动画
  102. // chart.series[0].addPoint(18);
  103. // chart.series[0].addPoint([12]);
  104. // chart.series[0].addPoint([v.x, v.y]);
  105. // 参数:是否重绘
  106. // chart.series[0].remove(false);
  107. // 更新饼图
  108. // $('#id1').highcharts().series[0].data[0].update({x: 0, y: 100})

临时放一下

框架----Django框架知识点整理的更多相关文章

  1. WEB框架-Django框架学习-预备知识

    今日份整理,终于开始整个阶段学习的后期了,今日开始学习Django的框架,加油,你是最胖的! 1.web基础知识 1.1 web应用 Web应用程序是一种可以通过Web访问的应用程序,程序的最大好处是 ...

  2. web 框架的本质及自定义web框架 模板渲染jinja2 mvc 和 mtv框架 Django框架的下载安装 基于Django实现的一个简单示例

    Django基础一之web框架的本质 本节目录 一 web框架的本质及自定义web框架 二 模板渲染JinJa2 三 MVC和MTV框架 四 Django的下载安装 五 基于Django实现的一个简单 ...

  3. day64 django django零碎知识点整理

    本文转载自紫金葫芦,哪吒,liwenzhou.cnblog博客地址 简单了解mvc框架和MTV框架, mvc是一种简单的软件架构模式: m----model,模型 v---view,视图 c---co ...

  4. 框架----Django框架(基础篇)

    一.基本配置 一.创建django程序 终端命令:django-admin startproject sitename IDE创建Django程序时,本质上都是自动执行上述命令 其他常用命令: pyt ...

  5. python 之 Django框架(Django框架简介、视图装饰器、request对象、Response对象)

    12.33 Django框架简介: MVC,全名是Model View Controller,是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model).视图(View)和控制器( ...

  6. beego 框架基本使用 && 知识点整理

    beego 官网的教程已经整理的非常详细了,但作为一个刚接触的学习者,还是有必要做一下整理,这样在后面使用的时候遇到了不太熟悉的地方,还能反过头来看下自己整理的内容,快速的把知识再捞回来,下面是对官网 ...

  7. WEB框架-Django框架学习(二)- 模型层

    今日份整理为模型层 1.ORM简介 MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库, ...

  8. 框架----Django框架(进阶篇)

    一.Model 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接数据库,并编写数据访问层代码 业务逻辑层去调用数据访问层 ...

  9. WEB框架-Django框架学习-关联管理器(RelatedManager)

    一.class RelatedManager "关联管理器"是在一对多或者多对多的关联上下文中使用的管理器.它存在于下面两种情况: 1.一对多 ForeignKey关系的“另一边” ...

随机推荐

  1. 接口自动化之接口工具选取(jmeter)

    jmeter进行接口测试,网上简易教程很多 其实关于HTTP接口测试的实现,网上还有很多其他工具诸如:http在线请求测试/谷歌插件postman/火狐插件等. 至于选择jmeter的原因,其实没有原 ...

  2. TW实习日记:第五天

    今天可以说是非常忙的一天了,要再项目中实现微信相关的功能:授权登录以及扫码登录,还有就是自建应用的发送消息.首先功能代码其实在经过了几天的学习之后并没有很难,但是最让我难受的是在项目中去加代码,首先s ...

  3. 《图解 HTTP 》阅读 —— 第五章

    第5章 与HTTP协作的web服务器 一台服务器可以托管多个域名. 在相同的IP地址下,虚拟主机可以寄存多个不同主机名和域名的网站,所以在发送HTTP请求时,必须在Host首部内指定完整的主机名和域名 ...

  4. hdu6447

    YJJ's Salesman Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)To ...

  5. log4j 配置使用

    使用log4j来管理日志信息,非常方便,下面简单介绍一下整个使用流程: 1.创建简单java项目 2.在类路径下新建log4j.properties文件 3.配置log4j.properties文件 ...

  6. 关于jsonp跨域的 实现

    1.实现原理    1.把接口写在 script标签的src 中 这个接口就可以访问(不会存在跨域问题  因为接口在浏览器地址栏是可以访问的  会返回json字符串); 2.直接写不可以  因为正常情 ...

  7. Live Love(思维)

    DreamGrid is playing the music game Live Love. He has just finished a song consisting of n notes and ...

  8. “取件帮”微信小程序宣传视频链接及内容介绍

    1.视频链接 视频上传至优酷自频道,地址链接:http://v.youku.com/v_show/id_XMzg2NTM3OTc5Ng==.html?spm=a2hzp.8253869.0.0 2.视 ...

  9. Oracle数据库表空间常用操作

    1. 查看所有表空间大小 SQL> select tablespace_name,sum(bytes)/1024/1024 from dba_data_files group by tables ...

  10. 使用ASP.NET Identity 实现WebAPI接口的Oauth身份验证

    使用ASP.NET Identity 实现WebAPI接口的Oauth身份验证   目前WEB 前后端分离的开发模式比较流行,之前做过的几个小项目也都是前后分离的模式,后端使用asp.net weba ...