Django面试题

news2024/11/17 1:30:35

1. 什么是wsgi?

WSGI 是 “Web Server Gateway Interface” 的缩写,它是一种用于 Python Web 应用程序和 Web 服务器之间通信的标准接口。它定义了一组规则和约定,使 Web 服务器能够与任何符合 WSGI 规范的 Python Web 应用程序进行交互。
###\ WSGI 的作用

WSGI 的作用是将 Web 服务器与 Python Web 应用程序解耦,使它们能够独立开发和部署。这使得 Web 服务器可以支持多种不同的 Python Web 框架,而无需修改其代码。
###\ WSGI 的工作原理

WSGI 的工作原理如下:

  1. Web 服务器接收到一个 HTTP 请求。
  2. Web 服务器将请求传递给 WSGI 应用程序。
  3. WSGI 应用程序处理请求并生成一个 HTTP 响应。
  4. Web 服务器将响应返回给客户端。

2. asgi和wsgi的异同

WSGI和ASGI,都是基于Python设计的网关接口(Gateway Interface,GI)

WSGI是基于http协议模式开发的,不支持websocket
ASGI不仅支持当前的web开发中的一些新的协议标准,同时ASGI支持原有模式和Websocket的扩展,即ASGI是WSGI的扩展。

网关接口(Gateway Interface,GI)

网关接口是一个定义了 Web 服务器Web 应用程序之间通信方式的规范。只有Web应用程序都实现了网关接口规范后,双方的通信才能顺利完成。常见的网关接口协议:CGI、FASTAPI、WSGI、ASGI。
在这里插入图片描述

web服务器 && web应用程序

Web 服务器

Web 服务器 是一个软件程序,它运行在计算机上,用于处理来自客户端(例如浏览器)的 HTTP 请求,并向客户端发送响应。

Web 服务器的主要功能包括:

  • 接收来自客户端的 HTTP 请求
  • 处理 HTTP 请求并解析 URL
  • 查找请求的资源(例如 HTML 文件、图像文件)
  • 将资源的内容发送给客户端
  • 处理 HTTP 头和状态码
  • 处理 Cookie 和会话

Web 应用程序

Web 应用程序 是一个运行在 Web 服务器上的软件程序,它用于处理来自客户端的 HTTP 请求并生成动态内容。Web 应用程序通常使用编程语言(例如 Python、PHP、Java)编写,并使用数据库来存储数据。

Web 应用程序的主要功能包括:

  • 处理来自客户端的 HTTP 请求
  • 生成动态内容(例如 HTML 页面、JSON 数据)
  • 访问数据库
  • 处理用户输入
  • 处理会话
    在这里插入图片描述

Web 服务器和 Web 应用程序的区别

特征Web 服务器Web 应用程序
功能处理 HTTP 请求并发送静态内容处理 HTTP 请求并生成动态内容
编程语言C、C++Python、PHP、Java
数据库通常不使用通常使用
可扩展性更高更低
示例Apache、Nginx、IISDjango、Flask、WordPress

在这里插入图片描述

3. django请求的生命周期?

  • 当用户在浏览器中输入url时,浏览器会生成请求头和请求体发给服务端
  • 服务端的wsgiref模块接收用户请求并将请求进行初次封装
  • 将请求交给Django的中间件
  • 通过中间件之后将请求交给url,根据浏览器发送的不同url去匹配不同的视图函数
  • 视图函数根据业务逻辑调用数据库获取相应的数据,然或根据模板渲染页面
  • 视图函数将响应的页面依次通过中间件
  • 到达wsgi,封装数据后反馈给客户端

在这里插入图片描述

4. 中间件

中间件的定义

中间件是一个用来处理Django的请求和响应的框架级别的钩子。它是一个轻量、低级别的插件系统,用于在全局范围内改变Django的输入和输出。每个中间件组件都负责做一些特定的功能。

说的直白一点中间件是帮助我们在视图函数执行之前和执行之后都可以做一些额外的操作,它本质上就是一个自定义类,类中定义了几个方法,Django框架会在请求的特定的时间去执行这些方法。

中间件的五个方法

  • process_request(self,request):请求进来时,权限认证
  • process_view(self, request, view_func, view_args, view_kwargs):路由匹配之后,能够得到视图函数
  • process_template_response(self,request,response):模板渲染时执行
  • process_exception(self, request, exception):异常时执行
  • process_response(self, request, response):请求有响应时执行

以上方法的返回值可以是None或一个HttpResponse对象。如果是None,则继续按照Django定义的规则向后继续执行,如果是HttpResponse对象,则直接将该对象返回给用户。

Django中间件

中间件执行流程

请求到达中间件之后,先按照正序执行每个注册中间件的process_reques方法,process_request方法返回的值是None,就依次执行,如果返回的值是HttpResponse对象,不再执行后面的process_request方法,而是执行当前对应中间件的process_response方法,将HttpResponse对象返回给浏览器。也就是说:如果MIDDLEWARE中注册了6个中间件,执行过程中,第3个中间件返回了一个HttpResponse对象,那么第4,5,6中间件的process_request和process_response方法都不执行,顺序执行3,2,1中间件的process_response方法。
在这里插入图片描述
 process_request方法都执行完后,匹配路由,找到要执行的视图函数,先不执行视图函数,先执行中间件中的process_view方法,process_view方法返回None,继续按顺序执行,所有process_view方法执行完后执行视图函数,按正序执行。假如中间件3 的process_view方法返回了HttpResponse对象,则4,5,6的process_view以及视图函数都不执行,直接从最后一个中间件,也就是中间件6的process_response方法开始倒序执行。

process_template_response和process_exception两个方法的触发是有条件的,执行顺序也是倒序。总结所有的执行流程如下:
在这里插入图片描述
注意:这里的正序指的是按照MIDDLEWARE中的注册顺序从前到后顺序执行的(在settings.py里面设置中 从下到上的顺序)。

在这里插入图片描述

5. 什么是CSRF,Django如何解决?

CSRF概念

CSRF(cross-site request forgery),简称跨站请求伪造。,攻击者可以利用用户的登录状态,在用户不知情的情况下,以用户的身份向网站发送恶意请求。

  • 受害者登录a.com,并保留了登录凭证(Cookie)。
  • 攻击者引诱受害者访问了b.com。
  • b.com 向 a.com 发送了一个请求:a.com/act=xx。浏览器会默认携带a.com的Cookie。
  • a.com接收到请求后,对请求进行验证,并确认是受害者的凭证,误以为是受害者自己发送的请求。
  • a.com以受害者的名义执行了act=xx。
  • 攻击完成,攻击者在受害者不知情的情况下,冒充受害者,让a.com执行了自己定义的操作。

Django中的CSRF实现机制

django通过django.middleware.csrf.CsrfViewMiddleware这个中间层来完成。

Django预防CSRF攻击的方法是在用户提交的表单中加入一个csrftoken的隐含值,这个值和服务器中保存的csrftoken的值相同,这样做的原理如下:

1、在用户访问django的可信站点时,django反馈给用户的表单中有一个隐含字段csrftoken,这个值是在服务器端随机生成的,每一次提交表单都会生成不同的值

2、当用户提交django的表单时,服务器校验这个表单的csrftoken是否和自己保存的一致,来判断用户的合法性

3、当用户被csrf攻击从其他站点发送精心编制的攻击请求时,由于其他站点不可能知道隐藏的csrftoken字段的信息这样在服务器端就会校验失败,攻击被成功防御

(每一次提交表单都会生成一个新的csrftoken,所以就算恶意获得一次token,再执行另一次表单提交时,也会校验失败)

在这里插入图片描述

6. Django如何实现websocket

Django使用Channels实现WebSocket的方法
官方文档

Django 的核心组件

  1. 对象关系映射(ORM):它将面向对象编程语言(如 Python)中的对象与关系型数据库(如 MySQL)中的表进行映射。ORM 允许使用面向对象的方式来操作数据库,而无需编写复杂的 SQL 语句。

在这里插入图片描述
2. URL分发器:定义 URL 模式和视图之间的映射的 Python 模块。它允许将 URL 映射到特定的视图函数,以便处理不同的请求
3. 视图:视图是用来处理 HTTP 请求和生成响应的函数。
4. 模板:用于将模板文件转换成 文件,并在浏览器上显示
5. 中间件:中间件是用来拦截和修改 HTTP 请求和响应的类。它们可以用于各种目的,例如身份验证、授权、缓存和日志记录。
6. 管理站点:管理站点是一个基于 Web 的界面,允许管理模型数据。它提供了一个用户友好的界面来创建、读取、更新和删除模型实例。
7. 表单序列化及验证系统 (Form):用于 表单和数据库存储的数据之间的转换

7. FBV & CBV

FBV (Function-Based View) 函数式视图 是 Django 中的一种视图类型,它使用 Python 函数来处理 HTTP 请求和生成响应。FBV 通常用于编写简单的视图,例如登录视图或注销视图。

CBV (Class-Based View) 类式视图 是 Django 中另一种视图类型,它使用 Python 类来处理 HTTP 请求和生成响应。CBV 通常用于编写更复杂的视图,例如列表视图或详细视图。

FBV 和 CBV 的主要区别在于:

  • 代码组织: FBV 的代码通常分散在多个函数中,而 CBV 的代码通常组织在一个类中。
  • 可重用性: CBV 通常比 FBV 更可重用,因为可以将 CBV 继承到其他 CBV 中,并重用其代码。
  • 可测试性: CBV 通常比 FBV 更可测试,因为可以使用单元测试框架来测试 CBV 的方法。

8. 如何给CBV的程序添加装饰器?

在类视图中使用为函数视图准备的装饰器时,不能直接添加装饰器,需要使用method_decorator将其转换为适用于类视图方法的装饰器。

在URL上添加

# urls.py
urlpatterns = [
  
    path("login/",views.Mydecorator(views.MyView.as_view())),
]

在类上添加,name=“函数名称”

@method_decorator(Mydecorator,name="post")
@method_decorator(Mydecorator,name="get")
class MyView(View):
    def get(self,request):
        return HttpResponse("get请求")
 
    def post(self,request):
        return HttpResponse("post请求")

在函数上添加

class MyView(View):
    @method_decorator(Mydecorator)
    def get(self,request):
        return HttpResponse("get请求")
 
    def post(self,request):
        return HttpResponse("post请求")

9. 列举django orm 中所有的方法

Django QuerySet 方法表格

方法描述
all()查询所有结果
filter(**kwargs)它包含了与所给筛选条件相匹配的对象。获取不到返回None
get(**kwargs)返回与所给筛选条件相匹配的对象,返回结果有且只有一个。获取不到会抱错#如果符合筛选条件的对象超过一个或者没有都会抛出错误
exclude(**kwargs)它包含了与所给筛选条件不匹配的对象
order_by(*field)对查询结果排序
reverse()对查询结果反向排序
count()返回数据库中匹配查询(QuerySet)的对象数量
first()返回第一条记录
last()返回最后一条记录
exists()如果QuerySet包含数据,就返回True,否则返回False
values(*field)返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系 model的实例化对象,而是一个可迭代的字典序列
values_list(*field)它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列
distinct()从返回结果中剔除重复纪录
bulk_create()批量创建数据

Django ORM 方法代码示例

1. all() 方法

from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=255)
    author = models.CharField(max_length=255)

# 查询所有图书
books = Book.objects.all()

# 打印所有图书的标题
for book in books:
    print(book.title)

2. filter() 方法

# 查询标题为 "Django" 的图书
books = Book.objects.filter(title="Django")

# 打印所有图书的标题和作者
for book in books:
    print(f"{book.title} by {book.author}")

3. get() 方法

# 获取主键为 1 的图书
book = Book.objects.get(pk=1)

# 打印图书的标题
print(book.title)

4. exclude() 方法

# 查询标题不为 "Django" 的图书
books = Book.objects.exclude(title="Django")

# 打印所有图书的标题
for book in books:
    print(book.title)

5. order_by() 方法

# 按标题升序排序图书
books = Book.objects.order_by("title")

# 打印所有图书的标题
for book in books:
    print(book.title)

6. reverse() 方法

# 按标题降序排序图书
books = Book.objects.order_by("title").reverse()

# 打印所有图书的标题
for book in books:
    print(book.title)

7. count() 方法

# 统计所有图书的数量
count = Book.objects.count()

# 打印图书数量
print(f"Total books: {count}")

8. first() 方法

# 获取第一个图书
book = Book.objects.first()

# 打印图书的标题
print(book.title)

9. last() 方法

# 获取最后一个图书
book = Book.objects.last()

# 打印图书的标题
print(book.title)

10. exists() 方法

# 检查标题为 "Django" 的图书是否存在
exists = Book.objects.filter(title="Django").exists()

# 打印结果
print(f"Book with title 'Django' exists: {exists}")

11. values() 方法

# 获取所有图书的标题和作者
values = Book.objects.values("title", "author")

# 打印所有图书的标题和作者
for value in values:
    print(f"{value['title']} by {value['author']}")

12. values_list() 方法

# 获取所有图书的标题和作者
values_list = Book.objects.values_list("title", "author")

# 打印所有图书的标题和作者
for value in values_list:
    print(f"{value[0]} by {value[1]}")

13. distinct() 方法

# 剔除重复的作者
authors = Book.objects.values_list("author", flat=True).distinct()

# 打印所有作者
for author in authors:
    print(author)

10. select_related和prefetch_related的区别?

select_related

select_related通过多表join关联查询,一次性获得所有数据,通过降低数据库查询次数来提升性能,但关联表不能太多,因为join操作本来就比较消耗性能。

# 获取id=1的文章对象同时,获取其相关username信息
Article.objects.select_related('username').get(id=1)
 
# 获取id=1的文章对象同时,获取其相关作者名字信息
Article.objects.select_related('username__username').get(id=1)
 
# 获取id=1的文章对象同时,获取其相关tag和相关作者名字信息。下面方法等同。
# 方式一:
Article.objects.select_related('tag', 'username__username').get(id=1)
# 方式二:
Article.objects.select_related('tag').select_related('username__username').get(id=1)
 
# 使用select_related()可返回所有相关主键信息。all()非必需。
Article.objects.all().select_related()
 
# 获取Article信息同时获取username信息。filter方法和selected_related方法顺序不重要。
# 方式一:
Article.objects.filter(tag__gt=3).select_related('username')
# 方式二:
Article.objects.select_related('username').filter(tag__gt=3)

prefetch_related

prefetch_related不在数据库中进行连接,而是在python中连接,不创建带join的SQL语句

articles = Article.objects.all().select_related('category').prefecth_related('tags')
 
# 文章列表及每篇文章的tags对象名字信息
Article.objects.all().prefetch_related('tags__name')
 
# 获取id=13的文章对象同时,获取其相关tags信息
Article.objects.prefetch_related('tags').get(id=13)
 
# 获取文章列表及每篇文章相关的名字以P开头的tags对象信息
Article.objects.all().prefetch_related(
    Prefetch('tags', queryset=Tag.objects.filter(name__startswith="P"))
)
 
# 文章列表及每篇文章的名字以P开头的tags对象信息, 放在article_p_tag列表
Article.objects.all().prefetch_related(
    Prefetch('tags', queryset=Tag.objects.filter(name__startswith="P")),
to_attr='article_p_tag'
)
  • 对与单对单或单对多外键ForeignKey字段,使用select_related方法
  • 对于多对多字段和反向外键关系,使用prefetch_related方法
  • 两种方法均支持双下划线指定需要查询的关联对象的字段名

select_related和prefetch_related的用法与区别
select_related和prefetch_related的使用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1812508.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Javascript学习之路:js中关于遍历总结

循环/遍历 循环,就是一遍又一遍的重复执行相同或者相似的代码循环结构的两个要素 循环体–要执行的相同或相似的语句循环条件–重复执行的次数,或者继续执行循环的条件 👉while循环 while循环语法格式 while(boolean表达式){循环体语句}//…

3D高斯泼溅原理及实践【3DGS】

人工智能可能是我们这个时代的主要领域之一,它几乎可以用于从驾驶汽车到医疗保健甚至能够预防失明等所有领域,最近提出了一种新的 3D 重建方法。SNGULAR 及其人工智能团队希望了解有关 3D 重建技术的最新更新的更多信息。 目前可用于 3D 重建的许多 SOT…

[干货!必看文章]学会如何用L4级AI软件开发平台免费制作应用程序

前言: 自从ChatGPT问世以来,就掀起了全球AI大模型的浪潮。国外有Claude,Llama,Grok,Suno,国内有kimi,有智谱AI,有通义千问,还有文心一言... 国内大模型市场规模已经达到了…

【Python/Pytorch - 网络模型】-- 手把手搭建U-Net模型

文章目录 文章目录 00 写在前面01 基于Pytorch版本的UNet代码02 论文下载 00 写在前面 通过U-Net代码学习,可以学习基于Pytorch的网络结构模块化编程,对于后续学习其他更复杂网络模型,有很大的帮助作用。 在01中,可以根据U-Net…

瓦片边界可视化工具

本文涉及的核心内容 瓦片边界可视化-VisibleTileBoundariesmeethigher/visible-tile-boundaries: visible tiles boundaries demo 一、瓦片边界可视化 1.1 背景 日常GIS开发中,需要了解瓦片是什么,瓦片展示的效果是什么样的。这种口头上抽象的东西&a…

计算机哈佛架构、冯·诺依曼架构对比

哈佛架构和冯诺依曼架构是两种不同的计算机系统架构,它们在存储器组织方式上有着显著的区别。下面是它们的原理、优缺点的对比以及一些常见的 MCU 采用的架构: 哈佛架构: 原理:哈佛架构将指令存储器(程序存储器&#x…

Androd adb命令汇总,app专项测试命令。

1.普通命令 1.1 devices命令 # 语法格式 :adb devices [-l] # 作用 :返回已连接设备的信息 # 示例 :adb devices : 返回设备的信息adb devices -l : 返回设备的详细信息1.2 help命令 # 语法格式 :adb --help # 作用 &…

攻防世界--杂项misc-2017_Dating_in_Singapore

题目信息 题目描述和附件分别是一串数字和新加坡日历,数字中间有短线-连接,刚好分成了12个字段。猜想对应了12个月 01081522291516170310172431-050607132027262728-0102030209162330-02091623020310090910172423-02010814222930-0605041118252627-020…

集合进阶(接口Collection(迭代器、增强for、Lambda表达式)、List中常见的方法和五种遍历方式、数据结构(栈、队列、数组、链表)

一、单列集合顶层Collection List系列集合:添加的元素是有序、可重复、有索引Set系列集合:添加的元素是无序、不重复、无索引 Collection是单列集合的祖宗接口,它的功能是全部单列集合都可以继承使用的。 Collection的遍历方式 1、迭代器——…

catia零件装配中通过指南针移动零件

1 将零件导入进来后 2 把指南针移动到零件上 具体移动哪个可以通过模型树点击选中,选中那个就可以移动那个。 这种情况需要注意的是 需要双击选择要移动零件的父节点 如下图,Product2蓝色表示是激活的,这样才可以单击选中下面的零件后通过…

STM32F103RCT6换STM32F103C8T6后delay函数延时了10倍

更换单片机步骤: 1、型号选择 2、启动文件,将HD改为MD。 3、引入对应的启动文件。 4、后面发现delay比之前延时了差不多10倍,解决办法:在初始化后加入SystemInit();即可。

Frontiers旗下期刊,23年分区表整理出炉!它还值得投吗?

本周投稿推荐 SSCI • 中科院2区,6.0-7.0(录用友好) EI • 各领域沾边均可(2天录用) CNKI • 7天录用-检索(急录友好) SCI&EI • 4区生物医学类,0.5-1.0(录用…

第十五届蓝桥杯pb组国赛E题[马与象] (15分)BFS算法 详解

博客主页:誓则盟约 系列专栏:IT竞赛 专栏 关注博主,后期持续更新系列文章 如果有错误感谢请大家批评指出,及时修改 感谢大家点赞👍收藏⭐评论✍ 问题描述: 小蓝有一个大小为 N N 的棋盘(棋…

110.网络游戏逆向分析与漏洞攻防-装备系统数据分析-装备与技能描述信息的处理

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 如果看不懂、不知道现在做的什么,那就跟着做完看效果,代码看不懂是正常的,只要会抄就行,抄着抄着就能懂了 内容…

javaWeb项目-ssm+vue医院住院信息管理系统功能介绍

项目关键技术 开发工具:IDEA 、Eclipse 编程语言: Java 数据库: MySQL5.7 框架:ssm、Springboot 前端:Vue、ElementUI 关键技术:springboot、SSM、vue、MYSQL、MAVEN 数据库工具:Navicat、SQLyog 1、Java简介 现代社…

Nvidia/算能 +FPGA+AI大算力边缘计算盒子:AI智能监控 用于沙滩救援

以色列的一个团队在人工智能领域取得的成果引起了轰动。 今天他们取得的成果源于多年前的一个想法。Netanel Eliav 和 Adam Bismut 是校园时代的旧伙伴,当时他们想要解决一个可以改变世界的问题,由此引出这样一个想法:溺水的 Bismut 漂流到死…

RV32M指令集

RV32M指令集 1、乘法运算2、除法运算1、乘法运算 MUL 指令(得到整数32位乘积(64位中的低32位)) MUL 指令用于执行两个带符号或无符号整数之间的乘法运算。其语法如下: mul rd, rs1, rs2 它将寄存器 rs1 和 rs2 中的值相乘,并将结果写入寄存器 rd 中。如果 rs1 和 rs2 都是有…

catia零件装配时预览零件的形状

这样的显示方式看不到 选择大或中图标就可预览零件形状

基于STM32的智能水产养殖系统(二)

TPS5433IDR TPS5433IDR 是一款由德州仪器 (Texas Instruments) 生产的高效降压转换器(Buck Converter)。它能够将较高的输入电压转换为较低的输出电压,适用于各种电源管理应用。 主要特性 输入电压范围: 5.5V 至 36V输出电压范围: 0.9V 至 …

惊艳的短视频:成都科成博通文化传媒公司

惊艳的短视频:瞬间之美,震撼心灵 在数字化时代,短视频以其短小精悍、内容丰富的特点,迅速占领了我们的屏幕和时间。而在这个浩如烟海的视频海洋中,总有一些短视频能够脱颖而出,以其惊艳的视觉效果、深刻的…