首页 > 其他分享 >django周报

django周报

时间:2022-12-18 21:45:26浏览次数:37  
标签:name models django filter objects login 查询 周报

Django请求生命周期

用户在浏览器输入url 发送一个get请求方法的request请求

django中封装了wsgi服务器用来监听端口接受request请求

接收到的请求封装后传入中间件 然后中间件在传入路由分发 再匹配对应的视图函数

视图函数进行业务逻辑处理 然后需要数据相关调用 modles表中对象 通过orm拿到数据库数据,

最后在templates中对应模板进行渲染 渲染好后再传入中间件 通过wsgi再次封装返给浏览器进行展示

路由匹配

在urls.py文件中

1.正则匹配

re_path模块 这样才可以使用正则匹配

re_path('^login/', user_info.views.login),

re_path后面可以直接跟正则表达式 可以用用户输入的路由中进行匹配,只要匹配到了 就会停止对其他 会立即执行对应的视图函数

2.无名分组和有名分组

    re_path('^test/(\d+)/', user_info.views.login),

无名分组 通过位置传参 可以传递一个符合(\d+)的参数后端可以接收

re_path('^test/(?P<id>\d+)/', user_info.views.login),

有名分组 通过关键词传参 这里设置的关键词叫id 那后端接收这个传参的时候也要交id,需要和这里辉映 属于给正则起名字 进行关键字传参

    path('home/<str:info>', user_info.views.home),

转换器 更加方便 直接接收所有字符串 也是关键字传参方式

反向解析

re_path('^login/<str:id>', user_info.views.login,name='login')

前端 
{% url 'login' 123 %}
# 相当于给路由别名为 login对应的函数传递了一个关键字传参 id=123

可以给路由起别名 前端页面可以通过反向解析直接给这个路由函数传参

路由分发

当多个人协同开发 可以有多个app 每个app都可以有自己独自的

urls.py文件 也 自己的templates文件

开发完成后需要全部提交 然后负责人归纳做一个路由分发即可

子路由也就是app内的路由设置 正常设置即可

总路由 根目录下的urls.py文件 为了实现路由分发 需要模块

include模块

from django.urls import path,include,

urlpatterns = [
    path('admin/', admin.site.urls),
    re_path('^app01/',include('app01.urls')),
    re_path('^app02/',include('app02.urls')),
    re_path('^app03/',include('app03.urls')),
]

使用正则表达式匹配对应的app文件 然后传入对应的app视图层进行匹配视图函数

名称空间

一个django项目中不可以出现路由别名一样的,这样就会导致名称空间问题

所以当我们路由层起别名时 最好加上app前缀 这样就会导致没有相同的路由别名

确保反向解析没有问题

app01 urls.py
urlpatterns = [  path('login/', views.login, name='app01_login') ]

app02 urls.py
urlpatterns = [path('login/', views.login, name='app02_login')]


前端反向解析:{% url 'app01_login' %} {% url 'app02_login' %}
后端也可以直接重定向

虚拟环境

虚拟环境关键词
venv

在CMD终端创建虚拟环境:  python -m venv pyvenv38

虚拟环境:能够针对相同版本的解释器创建多个分身 每个分身可以有自己独立的环境

视图层三板斧

HttpResponse
用来处理请求的视图函数都必须返回HttpResponse对象
返回字符串类型 

render
返回html页面 还可以给页面传值
使用字典传值
locals()关键字 传递所有变量名到html页面
return render(request, 'update.html', {name:values} )
return render(request, 'update.html', locals() )
              
              
redirect('路由别名')
重定向 

jsonResponse对象

前后端交互需要用到json格式

from django.http import JsonResponse
   return JsonResponse(user_dict)


return JsonResponse(user_dict)
传送字典可以直接返回

l1 = [11,22,33,44]

return JsonResponse(l1,safe=False)
传送列表需要 safe=False

form如何上传文件/request对象获取文件

form表单上传文件

<form action='' method='post' enctype ='multipart/form-data'>
首先必须是 post请求 其次 要配置  enctype属性

后端获取文件
request.FILES.get('file')
这样来接受文件对象

然后储存文件

with open(file_obj.name,'wb') as f:
   for line in file_obj:
       f.write(line)
        

request对象基本方法

request.method 
获取请求方式
request.POST
获取post请求提交的普通键值对数据 不包括文件
request.GET
获取get请求
request.FILES
获取文件

request.path
获取用户访问的路由

request.path_info

request.get_full_path()
获取用户访问的路由及问号后面携带的参数

FBV与CBV

FBV是基于函数的是视图
CBV是基于类的视图

CBV是创建类 路由访问类里面的方法 
from django.views import View

class Mylogin(View):
  def get(self,request):
    return render(request,'login.html')
  def post(self,request): 
    return render(request,'login.html')
  
  
 使用CBV和路由匹配时 需要用关键词 as_view() 方法
urlpatterns = [
    path('login/', views.Mylogin.as_view()),
]

'''
FBV和CBV各有千秋

CBV特点能够直接根据请求方式不同匹配到对应的方法执行

CBV源码解析

封装了一个函数,作为对应路由的函数
封装的函数中,让我们的自定义类产生了一个对象,并让对象执行方法dispatch返回结果
dispatch辨认了请求方式,根据请求方式返回了某个类体函数的结果(HttpResponse对象)

模板层语法传递数据

前端语法:
{{}}:主要与数据值相关
{%%}:主要与逻辑相关

前端html文件中可以使用

{{获取到后端传送的数据}}
<p> {{ name }} </p>
<p> {{ age }}  </p>
<P> {{ list.1}} </p>	
针对可以进行索引取值的数据 可以通过.数字的方法进行索引取值

给后端发送数据
<a href="{% url 'a01' '123' %}">点我</a>
# 跳转到 别名为 a01的路由 顺便给这个路由对应的函数 传递参数123



后端python文件中

#方式一:
def login(request):
    name = '张无忌'
    age = 22
    return render(request,'login.html',{'name'=name})
    #精准传值 不浪费资源 针对多资源的传递书写麻烦 优点:不浪费资源 

#方式二:关键词 locals()
def login(request):
    name = '张无忌'
    age = 22
    return render(request,'login.html',locals())
    #将方法中所有的变量名与值全部和html文件一起传送过去
    #优点方便一下传所有  缺点不够精准 浪费资源
    
后端传值特性
   1.基本数据类型都可以传递
   2.对象也可以传 
   3.文件对象也可以展示并调用方法
   4.函数名会自动加括号执行并将返回值展示到页面上(不支持额外传参)
   5.类名也会自动加括号调用
  
ps:总结针对可以加括号调用的名字模板语法都会自动加括号调用

模板层之过滤器

在Django的模板语言中,通过使用 过滤器 来改变变量的显示

使用管道符"|"来应用过滤器

在前端使用 可以对数据进行2次加工  

{{value|length}}  返回值的长度

{{value|filesizeformat}} 字段转换数字单位 变为文件大小

{{value|slice:"0:5"}}  对数据进行切片展示 索引0-5

{{ value|date:"Y-m-d H:i:s"}} 可以对时间进行格式化展示 '2022-01-19 18:12:23'

{{ value|safe}} 后端返回的值为前端标签时 控制是否直接展示


{{ value|truncatechars:9}} 如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“...”)结尾。
参数:截断的字符数

{{ value|truncatewords:9}} 在一定数量的字后截断字符串。


{{ value|cut:' ' }}
移除value指定字符
如果value为'i love you',那么将输出'iloveyou'.

模板层之逻辑判断

django中前端也是可以做逻辑判断的

if判断

{% if name == 'moon'%}
    条件符号执行的代码
{% elif name == '123'%}
    条件符号执行的代码
{% else %}
    以上条件都不符号时执行的代码
{% endif %}

固定语法一定要有结束 {% endif %
            
for循环

 {% for book_obj in book_obj_list %}
  <tr>
      <td>{{ forloop.counter }}</td>
      <td>{{ book_obj.name }}</td>
      <td>{{ book_obj.time|date:'Y-m-d' }}
       </td>
      {% endfor %}
      
for循环有自带方法
            
forloop.counter	    当前循环的索引值(从1开始)
forloop.counter0	  当前循环的索引值(从0开始)
forloop.revcounter	当前循环的倒序索引值(从1开始)
forloop.revcounter0	当前循环的倒序索引值(从0开始)
forloop.first	当前循环是不是第一次循环(布尔值)
forloop.last	当前循环是不是最后一次循环(布尔值)
forloop.parentloop	本层循环的外层循环

模板的继承与导入

html的复用

可以设置哪些可以变

关键词 母版设置可变区域
{% block 别名 %}


{% endblock %}


如何引入模板 
{% extends '母版文件名' %}


然后直接在内容区域编写改变的代码

{% block 母版可修改位置 %}
# 正常母版有3个可以修改的位置

{% endblock %}


ps:模板中至少应该有三个区域
   页面内容区、css样式区、js代码区


测试环境

创建一个text.py文件

导入模块 from django.test import TestCase

然后去manage.py中复制前两行

然后在 def main函数中 导入模块

import django
django.setup()

这样就可以测试你的代码了

如何时时查看orm底层执行的sql文件

sttings文件中配置

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level': 'DEBUG',
        },
    }
}

这样每次运行models命令都会显示对于的sql语句

orm常用关键字

create

表中新增数据,并有返回值是创建的对象本身

res = models.User.objects.create(name='moon',age=18)


filter()
筛选 支持多个条件 默认是 多个条件是and关系

res = models.User.objects.filter(name='moon')


update()
更新数据 搭配筛选来决定更新的个数
res = models.User.objects.filter(id=1).update(age=22)  

delete()
删除数据 搭配筛选来决定删除的个数
res = models.User.objects.filter(id=1).delete() 

all()
查询所有数据
models.User.objects.all()


values()
models.User.objects.filter(id=1).values('name')
print(res)  # <QuerySet [{},{},{}]>   列表套字典
# #获取user表中id为1的数据 的 name字段的值


values_list()
指定字段获取内容
# <QuerySet [('duo',), ('bo',), ('duoduo',), ('bo',), ('hong',)]>

distinct()
将查询的结果去重,不影响数据库中的数据
models.User.objects.values('name','age').distinct()


order_by()
根据指定条件排序 默认升序
models.User.objects.order_by('age')
# user表进行排序 排序根据为age 默认升序 从小到大


count()
models.User.objects.filter(age=22).count()
# 统计user表中 age是22的有几个

ORM执行编写SQL语句

复杂数据查询时候orm的操作效率可能比较低 没有原生的sql效率高,我们也可以自己编写sql

raw方法
res = models.User.objects.raw('select * from app01_user;')

方式二:
    from django.db import connection
    cursor = connection.cursor()
    cursor.execute('select name from app01_user;')
    print(cursor.fetchall())
    
    # 利用模块生成 cursor对象 然后利用cursor执行sql语句
    # cursor.fetchall() 接收反馈结果



双下划线查询

大于 小于 大于等于 小于等于 区间 包含等查询方式

更多筛选方式

通过.filter()方法获得数据,支持双下划线查询

models.User.objects.filter(age__gt=18)
# 查询年龄大于18的数据对象

models.User.objects.filter(age__lt=18)
# 查询年龄小于18的数据对象

models.User.objects.filter(age__gte=18)
#大于等于
models.User.objects.filter(age__lte=18)
#小于等于

models.User.objects.filter(age__in=(18,28,38))
# 查询年龄是 18 或者 28 或者 38的数据对象

models.User.objects.filter(age__range=(10,20))
# 查询年龄从10到20岁  之间 的数据对象

models.User.objects.filter(name__contains='m')
# 查询name字段中 包含 'm' 的数据对象 不包括大写M
models.User.objects.filter(name__icontains='m')
# 也包含大写的M

ORM表外键字段的创建

一对多

publish = models.ForeignKey(to='Publish',on_delete=models.CASCADE)
# 在表中建立外接字段


多对多
外键字段名 = models.ManyToManyField(to='关联表名')


一对一
author_info = models.OneToOneField(to='Author_info')



外键字段的增删改查

一对一或者一对多


models.Book.objects.create (name='西记',price='100',publish_id=1)
# 直接在外键添加实际字段 填写id


models.Book.objects.create(name='西记',price='100',publish=publish_obj)
# 或者直接添加对象

models.Publish.objects.filter(pk=2).delete()


models.Publish.objects.filter(pk=2).update(publish_id=2)
models.Publish.objects.filter(pk=2).update(publish=publish_obj

多对多

直接使用对象点第三张表的方式

add添加
book_obj.authors.add(1,3)
# 这样相当于 给书的这个对象 绑定了 1和3 2个id的作者


book_obj.authors.add(author_obj,author_obj2)
也支持直接放入一个对象

删除:
remove

book_obj.authors.remove(1,3)
book_obj.authors.remove(author_obj,author_obj2)


修改:
  set
  
  book_obj.authors.set([1,3])
  # 把数据对应的作者关系 更改为 这本书 对应作者id为 1和3
  
  
  清空:
  book_obj = models.Book.objects.filter(pk=1).first()
  book_obj.authors.clear()
  
  # 直接去authors这个表里面取消所有相关的绑定关系

正反向的概念

关键是看 外键字段在哪里

加入由书查出版社

因为外键字段在书内 所以就是正向查询

出版社查书 因为出版社内没有外键字段 就是 反向查询

多表查询

正向查询按字段

反向查询按表名小写

正向查询

查询书籍id为1的 出版社名称
book_obj = models.Book.objects.filter(pk=1).first()
book_obj.publish.name


查询作者为'moon'的电话号码
authors_obj = models.Authors.objects.filter(name='moon').first()
authors_obj.info.phone

ORM跨表查询的口诀(重要)
	正向查询按外键字段
	反向查询按表名小写

反向查询
查询是东方出版社出版的书

 publish_obj = models.Publish.objects.filter(name='东方出版社').first()

 publish_obj.book_set.all()

当你的查询结果是多个的时候 必须要用 _set.all()


联表查询(基于双下划线方法的)

1.查询作者'moon'的 手机号
authors_obj = models.Authors.objects.filter(name='moon').

2.查询数据id为1的出版社名称和书的名称
models.Book.objects.filter(pk=1).values(publish__name,name)
直接通过 ————跨表查询


ORM聚合查询

1.Max 最大值
2.Min 最小值
3.Sun 求和
4.Count 次数
5.Avg 平均值

未分组查询时需要关键词 aggregate

eg:查询商品表中所有商品价格的总和
models.Goods.objects.all().aggregate(Sun('price'))
models.Goods.objects.all().aggregate(Sun('price'),Max('supply'),Min('price')
# 同时获取 这个表中 不同的字段数据  price字段的和 supply字段的最大值等等


分组查询

分组关键字 annotate()

eg:统计每一本书的作者个数
一般只要需求中带有每个 每一个等词语 都是需要以此来分组比较合适


models.Book.objects.annotate
(author_num=Count('author__pk')).values('name','author_num')
# models.后面是什么就是根据什么分组 目前来看是根据Book来分组
# 然后获取分组后 统计出来每本书对应的作者个数 Count('author__pk') 
# 最后展示 书的名字 和 对应的作者个数


eg:统计不止一个作者的图书
res = models.Author.objects.annotate(author_num=Count(authors))
      .filter(author_num__gt=1).values('name','author_num')


# 先根据作者进行分组 求出每一本书对于的作者个数  author_num=Count(authors)
# 然后在过滤出作者个数大于1的作者对象  最后选择展示内容


'''
只要你手上是一个QuerySet对象 都可以使用 filter方法再次过滤
'''

F查询

**针对字段进行分组 **

eg:查出卖出数大于库存数的书籍
res = models.Book.objects.filter(maichu__gt=F('kuncun'))
使用f查询可以直接拿到字段的值

eg:将所有书的名称后面加上 打折

from django.db.models.functions import Concat

models.Book.objects.update(name=Concat(F('name').Value('打折')))
# F不可以直接做字符串的拼接 如果要做字符串的拼接需要导入 Concat模块
# 设置字符串的拼接 Concat(F('name').Value('打折')


Q查询

改变条件的链接关系

# filter(内默认是and关系)


eg:查询卖出数大于100或者价格小于600的书籍
from django.db.models import Q
models.Book.objects.filter(Q(maichu__gt=100)|Q(price__lt=600)
# 可以使用大Q包裹 然后 可以改变条件关系  
Q(条件),Q(条件) = and
Q(条件)|Q(条件) = or
~Q(条件)|~Q(条件) = not

标签:name,models,django,filter,objects,login,查询,周报
From: https://www.cnblogs.com/moongodnnn/p/16991005.html

相关文章

  • Django创建项目并连接数据库创建表
    创建Django项目利用pycharm直接创建,创建好之后删除templates文件夹以及settings.py里面的默认模板文件路径,后续项目使用前后端结合的方式,利用python的原生语法进行演示......
  • [附源码]Python计算机毕业设计Django图书馆出版物预订系统
    OverridetheentrypointofanimageIntroducedinGitLabandGitLabRunner9.4.Readmoreaboutthe extendedconfigurationoptions.Beforeexplainingtheav......
  • [附源码]Python计算机毕业设计Django水果管理系统
    OverridetheentrypointofanimageIntroducedinGitLabandGitLabRunner9.4.Readmoreaboutthe extendedconfigurationoptions.Beforeexplainingtheav......
  • [附源码]Python计算机毕业设计Django天狗电子商城系统
    OverridetheentrypointofanimageIntroducedinGitLabandGitLabRunner9.4.Readmoreaboutthe extendedconfigurationoptions.Beforeexplainingtheav......
  • django之图书管理系统、聚合与分组查询、F与Q查询
    一、图书管理系统讲解1.表设计 先考虑普通字段再考虑外键字段 数据库迁移、测试数据录入2.首页展示3.书籍展示4.书籍添加5.书籍编辑 后端如何获取用户想要编辑的数......
  • django总结
    内容导航django路由层内容详细django路由层1.路由匹配django2.X及以上path第一个参数些什么就匹配什么django1.X第一个参数是正则表达式无论匹配什么版本dja......
  • django 聚合查询 分组查询 f查询 q查询
    目录今日内容详细图书管理系统讲解聚合查询分组查询F与Q查询今日内容详细图书管理系统讲解1.表设计 先考虑普通字段再考虑外键字段 数据库迁移、测试数据录入2.首页......
  • 配置Django后端跨域
    一:安装django-cors-headers库 pipinstalldjango-cors-headers二:配置settings.py1.注册APP(在rest_framework后面添加)#注册APPINSTALLED_APPS=['rest_......
  • django7
    图书管理系统讲解1.表设计 先考虑普通字段再考虑外键字段 数据库迁移、测试数据录入2.首页展示3.书籍展示4.书籍添加5.书籍编辑 后端如何获取用户想要编辑的数据、......
  • django框架(五)
    将某个html的部分提前写好之后很多html页面想使用就可以导入直接在要导入的地方用以下代码即可:{%include'myform.html'%}#仅适用于页面某个小的区域,不适......