• 【2022秋招面经】——Django


    什么是Django?

    Django 是一个由 Python 编写的开放源代码的 Web 框架。使用 Django,只要很少的代码,Python 开发人员就可以轻松地完成一个正式网站所需要的大部分内容,并进一步开发出全功能的 Web 服务

    MVT模式

    Django 本身基于 MVT 模式。MVT 模式本质上和 MVC 是一样的,也是为了各组件间保持松耦合关系,只是定义上有些许不同,Django 的 MVT分别是指:

    • M 表示模型(Model):编写程序应有的功能,负责业务对象与数据库的映射(ORM)。
    • V 表示视图(View):负责业务逻辑,去 Model 中取数据,将数据返回给 Template。
    • T 表示模板 (Template):负责如何把页面(html)展示给用户。

    请添加图片描述

    补充 MVC 模式
    模型(Model)用于封装与应用程序的业务逻辑相关的数据以及对数据的处理方法。
    视图(View)能够实现数据有目的的提示
    控制器(Controller)起到不同层面的组织作用,用于控制应用程序的流程。处理事件并作出响应。”事件“包括用户的行为和数据Model上的改变。

    Django对web开发有哪些优势?
    • 功能完善、模块齐全
    • 自带后台管理系统 admin
    • 丰富的 Template 模板语言
    Django项目的组成模块
    • Project:工程项目承载了Django实例的所有settings的Python程序包;
    • Apps:单一工程的Web应用的Python程序包;
    • Model:负责Django的orm映射,描述数据库的布局,与数据库交互;
    • URLs:url请求映射表,将url请求和处理该请求的view做一个对应关系;
    • Views:处理HTTP请求;
    • Admin:提供一个专有管理员权限的用户添加、编辑、删除数据的界面;
    • Template:负责生成 HTML 界面
    Django的生命周期
    1. uWSGI服务器通过wsgi协议,将HttpRequest交给web框架 (Flask、Django)
    2. 首先到达request中间件,对请求对象进行校验或添加数据,例如:csrf、request.session,如果验证不通过直接跳转到response中间件
    3. 通过URL配置文件找到urls.py文件
    4. 根据浏览器发送的URL,通过视图中间件去匹配不同的视图函数或视图类,如果没有找到相对应的视图函数,就直接跳转到response中间件
    5. 在视图函数或视图类中进行业务逻辑处理,处理完返回到response中间件
    6. 模型类通过ORM获取数据库数据,并返回序列化json或渲染好的Template到response中间件
    7. 所有最后离开的响应都会到达response中间件,对响应的数据进行处理,返回HttpResponse给wsgi
    8. wsgi经过uWSGI服务器,将响应的内容发送给浏览器。

    http请求 -> 【uWSGI/wsig】 -> 【url】 -> 【view】 -> 【model & template】 -> 【uWSGI/wsig】-> 浏览器

    请添加图片描述

    什么是WSIG?

    WSGI(Web Server Gateway Interface,即Web服务器网关接口)是Python定义的Web服务器和Web应用程序或框架之间的一种简单而通用的接口。

    它是Python为了解决Web服务器端与客户端之间的通信问题而产生的,它基于现存的CGI标准而设计。

    其定义了Web服务器如何与Python应用程序进行交互,让Python写的Web应用程序可以和Web服务器对接起来。

    uwsgi、uWSGI和WSGI的区别?
    • uwsgi:是uWSGI服务器实现的独有协议,用于Nginx服务与uWSGI服务的通信规范;
    • uWSGI:是一个Web服务器,它实现了WSGI/uwsgi/HTTP等协议,用于接收Nginx转发的动态请求,处理后发个python应用程序;
    • WSGI:用在python web框架(Django/Flask)编写的应用程序与web服务器之间的接口,实现Web服务器与Python应用程序的交互。
    Django的HttpRequest对象是在什么时候创建的?

    请求走到WSGIHandler类的时候,执行cell方法,将environ封装成了request。

    class WSGIHandler(base.BaseHandler):
        request = self.request_class(environ)
    
    • 1
    • 2
    Django中间件

    中间件是 Django 请求/响应处理的钩子框架。它是一个轻量级的、低级的“插件”系统,用于全局改变 Django 的输入或输出。

    每个中间件组件都负责做一些特定的功能,常见的中间件有:

    1. process_request : 请求进来时,权限认证,csrf和session认证
    2. process_view : 路由匹配之后,能够得到视图函数
    3. process_exception : 异常时执行
    4. process_template_responseprocess : 模板渲染时执行
    5. process_response : 请求有响应时执行
    Django 对 http 请求的执行流程

    WSGI监听HTTP请求 ----> 将请求交给Handler处理 ---->

    • 在接收请求之前,启动一个支持 WSGI 网关协议的服务器监听端口等待外界 HTTP 请求,比如Django自带的开发者服务器或者uWSGI服务器。
    • Django 服务器根据WSGI协议指定相应的Handler来处理Http请求。
    • 在Handler中对已经符合WSGI协议标准规定的http请求进行分析,比如加载Django提供的中间件,路由分配,调用路由匹配的视图等。
    • 最后返回一个可以被浏览器解析的符合Http协议的HttpResponse。
    Django 中session的运行机制是什么
    • django的session存储可以利用中间件来实现。
    • 需要在 settings.py 文件中注册APP、设置中间件用于启动。
    • 设置存储模式(数据库/缓存/混合存储)和配置数据库缓存用于存储,生成django_session表单用于读写。
    什么是 CSRF
    • 黑客在恶意网站中写入了恶意脚本,脚本通常是银行转账的功能;
    • 用户在保持银行账户连接的情况下,访问了恶意网站,并触发了脚本;
    • 由于用户保持连接,脚本发送的转账请求也会包含用户的身份信息,从而通过验证。
    Web 框架的本质

    Web框架的本质是socket服务器,而用户的浏览器就是一个socket客户端,基于请求做出响应。客户端按照http协议发送请求,服务端做出对应的响应。

    对 restful 规范的认识

    restful是一种软件架构设计风格,并不是标准,它只是提供了一组设计原则和约束条件,主要用于客户端和服务器交互类的软件。

    就像设计模式一样,并不是一定要遵循这些原则,而是基于这个风格设计的软件可以更简洁,更有层次,我们可以根据开发的实际情况,做相应的改变。

    它里面提到了一些规范,例如
    1.restful 提倡面向资源编程,在url接口中尽量要使用名词,不要使用动词
    2.在url接口中推荐使用Https协议,让网络接口更加安全
    3.可以根据Http不同的method,进行不同的资源操作
    4.在url中可以体现版本号
    5.url中可以体现是否是API接口
    6.url中可以添加条件去筛选匹配
    7.响应式应该设置状态码
    8.有返回值,而且格式为统一的json格式
    9.返回错误信息
    10.返回结果中要提供帮助链接,即API最好做到Hypermedia

    Django中如何加载初始化数据?

    Django在创建对象时在调用save()方法后,ORM框架会把对象的属性写入到数据库中,实现对数据库的初始化。

    通过操作对象,查询数据库,将查询集返回给视图函数,通过模板语言展现在前端页面。

    Django缓存系统类型有哪些?
    1. 全站缓存,较少使用
    2. 视图缓存,用户视图函数或视图类中
    3. 模板缓存,指缓存不经常变换的模板片段
    简述Django下的(内建)缓存机制

    Django根据设置的缓存方式,浏览器第一次请求时,cache会缓存单个变量或整个网页等内容到硬盘或者内存中,同时设置response头部。

    当浏览器再次发起请求时,附带f-Modified-Since请求时间到Django。

    Django发现f-Modified-Since会先去参数之后,会与缓存中的过期时间相比较,如果缓存时间比较新,则会重新请求数据,并缓存起来然后返回response给客户端。

    如果缓存没有过期,则直接从缓存中提取数据,返回给response给客户端。

    什么是ASGI,简述WSGI和ASGI的关系与区别?

    ASGI是异步网关协议接口,一个介于网络协议服务和Python应用之间的标准接口,能够处理多种通用的协议类型,包括HTTP,HTTP2和WebSocket。

    WSGI是基于HTTP协议模式的,不支持WebSocket,而ASGI的诞生则是为了解决Python常用的WSGI不支持当前Web开发中的一些新的协议标准。

    同时,ASGI对于WSGI原有的模式的支持和WebSocket的扩展,即ASGI是WSGI的扩展。

    Django如何实现websocket?

    django实现websocket使用channels。

    channels通过http协议升级到websocket协议,保证实时通讯。

    也就是说,我们完全可以用channels实现我们的即时通讯,而不是使用长轮询和计时器方式来保证伪实时通讯。

    他使用asgi协议而不是wsgi协议,他通过改造django框架,使django既支持http协议又支持websocket协议。

    列举django的核心组件
    • 用于创建模型的对象关系映射,ORM;
    • 为最终用户设计较好的管理界面,Admin;
    • URL设计;
    • 设计者友好的模板语言,Template;
    • 缓存系统。
    路由优先匹配原则是什么?
    • 在url匹配列表中位置优先匹配如第1条和第2条同时满足匹配规则,则优先匹配第1条。
    • 如第1条为正则模糊匹配,第2条为精确匹配,也是优先匹配第1条
    urlpatterns中的name与namespace的区别

    name:给路由起一个别名

    namespace:防止多个应用之间的路由重复

    Django路由系统中include是干嘛用的?

    include用作路由转发,通常,我们会在每个app里,各自创建一个urls.py路由模块,然后从根路由出发,将app所属的url请求,全部转发到相应的urls.py模块中。

    Django重定向的几种方法,用的什么状态码?(初级)
    • HttpResponse
    • Redirect
    • Reverse

    状态码:302,301

    命令和make migrate 和make migrations的差别?(初级)

    make migrations:生成迁移文件

    migrate:执行迁移

    Django模型类关系有哪几种?(初级)
    • 一对一关系:OneToOneField
    • 一对多关系:ForeignKey
    • 多对多关系:ManyToManyField
    外键有什么用,什么时候合适使用外键 ,外键一定需要索引吗?

    程序很难100%保证数据的完整性,而用外键即使在数据库服务器宕机或异常的时候,也能够最大限度的保证数据的一致性和完整性。

    如果项目性能要求不高,安全要求高,建议使用外键,如果项目性能要求高,安全自己控制,不用外键,因为外键查询比较慢。

    加入外键的主要问题就是影响性能,因此加入索引能加快关联查询的速度。

    当删除一个外键的时候,其关联的表有几种处理方式?

    有6种处理方式:

    1. 同时删除父表和子表
      CASCADE:代表删除联级,父表(少类表)被删除的记录在子表(多类表)中所有字段也会被对应删除,模拟SQL语言中的ON DELETE CASCADE约束,将定义有外键的模型对象同时删除!(该操作为当前Django版本的默认操作!)

    2. 阻止删除父表
      PROTECT:阻止上面的删除操作,但是弹出ProtectedError异常

    3. 子表设置为空
      SET_NULL:代表父表(少类表)被删除后子表(多类表)对应的外键字段会设置为null,只有当字段设置了null=True,blank=True时,方可使用该值。

    4. 子表设置为默认值
      SET_DEFAULT:代表父表(少类表)被删除后子表(多类表)对应的外键字段会设置为默认值。只有当字段设置了default参数时,方可使用。

    5. 子表什么都不做
      DO_NOTHING:什么也不做,一切看数据库级别的约束

    6. 设置为一个传递给SET()的值或者一个回调函数的返回值
      SET():设置为一个传递给SET()的值或者一个回调函数的返回值。注意大小写,用得很少。

    django中怎么写原生SQL?
    1. 使用extra
    # 查询人民邮电出版社出版并且价格大于50元的书籍
    Book.objects.filter(publisher__name='人民邮电出版社').extra(where=['price>50'])
    
    • 1
    • 2
    1. 使用raw
    books=Book.objects.raw('select * from hello_book')
    for book in books:
    print(book)
    
    • 1
    • 2
    • 3
    1. 使用cursor
    from django.db import connection
    cursor = connection.cursor()
    cursor.execute("insert into hello_author(name) values ('特朗普')")
    cursor.execute("update hello_author set name='普京' WHERE name='特朗普'")
    cursor.execute("delete from hello_author where name='普京'")
    cursor.execute("select * from hello_author")
    cursor.fetchone()
    cursor.fetchall()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    谈一谈你对ORM的理解

    ORM是“对象-关系-映射”的简称。

    ORM是MVC或者MVC框架中包括一个重要的部分,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员的工作量,不需要面对因数据库变更而导致的无效劳动。

    Django的增删改查

    程序员无需考虑数据库语句的操作,也无需考虑是什么数据库,只需要对 model 及进行操作即可实现增删改查。

    # 创建、增加数据(推荐)
    models.UserInfo.objects.create(username='root',password='123')
    
    # 创建、增加数据
    obj = models.UserInfo(username='xsk',password='123')
    obj.save()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    # 删除指定多个字段的行
    models.UserInfo.objects.filter(username='root',password="123").delete()
    
    • 1
    • 2

    # 修改指定字段内的所有值变为888
    models.UserInfo.objects.all().update(password="888")
    
    # 修改指定id的行修改字段内的值
    models.UserInfo.objects.filter(id="3").update(password="777")
    
    • 1
    • 2
    • 3
    • 4
    • 5

    # 获取所有数据
    result = models.UserInfo.objects.all()
    
    # 只获取一条数据
    obj = models.UserInfo.objects.first(id=nid).first()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    Django的Queryset有哪些特性?

    Django 的 Queryset 主要有两个特性:一是惰性的(lazy),二是自带缓存的。

    例如这个查询:

    article_list = Article.objects.filter(title__contains="django")
    
    • 1

    在定义 article_list 的时候,Django的数据接口QuerySet并没有对数据库进行任何查询。无论你加多少过滤条件,Django都不会对数据库进行查询。只有当你需要对article_list做进一步运算时(比如打印出查询结果,判断是否存在,统计查询结果长度),Django才会真正执行对数据库的查询。这样设计的本意是尽量减少对数据库的无效操作,比如查询了结果而不用是计算资源的很大浪费。

    在例1中,当你遍历queryset(article_list)时,所有匹配的记录会从数据库获取。这些结果会载入内存并保存在queryset内置的cache中。这样如果你再次遍历或读取这个article_list时,Django就不需要重复查询了,这样也可以减少对数据库的查询。

    什么是基于函数的视图(FBV)和基于类的视图(CBV)以及各自的优点

    FBV(function base views) 就是在视图里使用函数处理请求。CBV(class base views) 就是在视图里使用类处理请求。Python是一个面向对象的编程语言,如果只用函数来开发,有很多面向对象的优点就错失了(继承、封装、多态)。

    CVB 主要优点:

    1. 提高代码的复用性,可以使用面向对象的技术,比如多继承;
    2. 可以用不同的函数针对不同的HTTP方法处理,而不是通过很多if判断,提高代码可读性。

    FVB 主要优点:

    • 简单易懂,对新手友好
    列举几个减少数据库查询次数的方法
    • 利用Django queryset的惰性和自带缓存的特性
    • 使用select_related和prefetch_related方法在数据库层面进行Join操作
    • 使用缓存
    Django 模型的继承方式?区别和使用场景?

    继承方式有:

    1. 抽象模型继承(abstract model)
    2. 多表模型继承(multi-table inheritance)
    3. 代理模型(proxy model)

    它们的区别如下:

    Django不会为抽象模型在数据库中生成自己的数据表。父类Meta中的abstract=True也不会传递给子类。如果你发现多模型有很多共同字段时,需使用抽象模型继承。

    多表模型继承与抽象模型继承最大的区别在于Django也会为父类模型建立自己的数据表,同时隐式地在父类和子类之间建立一个一对一关系

    如果我们只想改变某个模型的行为方法,而不是添加额外的字段或创建额外的数据表,我们就可以使用代理模型(proxy model)。设置一个代理模型,需要在子类模型Meta选项中设置proxy=True, Django不会为代理模型生成新的数据表。

    补充

    一、django面试题(21道)
    1、什么是wsgi?
    2、django请求的生命周期?
    3、列举django的内置组件?
    4、列举django中间件的5个方法?以及django中间件的应用场景?
    5、简述什么是FBV和CBV?
    6、django的request对象是在什么时候创建的?
    7、如何给CBV的程序添加装饰器?
    8、列举django orm 中所有的方法(QuerySet对象的所有方法)
    9、select_related和prefetch_related的区别?
    10、filter和exclude的区别?
    11、列举django orm中三种能写sql语句的方法
    12、values和values_list的区别?
    13、cookie和session的区别?
    14、如何使用django orm批量创建数据?
    15、django的Form组件中,如果字段中包含choices参数,请使用两种方式实现数据源实时更新。
    16、django的Model中的ForeignKey字段中的on_delete参数有什么作用?
    17、django的模板中自定义filter和simple_tag的区别?
    20、Django本身提供了runserver,为什么不能用来部署?(runserver与uWSGI的区别)
    21、Django如何实现websocket?

    二、Python面试宝典 - 基础篇 - 2020

    参考连接:

    1. 超详细的Django面试题
    2. 2020年最新Django经典面试问题与答案汇总(上)
  • 相关阅读:
    python subprocess.cal调用wkhtmltohtml中遇到的问题
    1、VS2019配置glfw和glad
    静态代码块和构造代码块
    【计算机网络】 TCP协议总结
    二维数组与二级指针是好朋友吗?
    网络基础(一)
    虚拟土地+VRGDA:一种可持续的元宇宙土地销售策略
    LIO-SAM 详读代码笔记 -- 3.imageProjection
    Github2024-04-25 开源项目日报Top10
    Linux基础指令(一)
  • 原文地址:https://blog.csdn.net/qq_41357569/article/details/127628699