欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 金融 > 【Python】笔试面试题之django篇

【Python】笔试面试题之django篇

2025/2/13 18:53:25 来源:https://blog.csdn.net/u014608435/article/details/145184696  浏览:    关键词:【Python】笔试面试题之django篇

文章目录

  • 面试题一:什么是wsgi?
  • 面试题二:描述一下django请求的生命周期?
  • 面试题三:谈谈django的orm优化操作
  • 面试题四:列举django中间件的5个方法?以及django中间件的应用场景?
  • 面试题五:django中如何实现orm表中添加数据时创建一条日志记录?
  • 面试题六:django缓存如何设置?
    • 使用缓存的五种情况
  • 面试题七:对cookies与session的了解?他们能单独用吗?

个人主页:道友老李
欢迎加入社区:道友老李的学习社区

面试题一:什么是wsgi?

全称 Python Web Server Gateway Interface,指定了web服务器和Python web应用或web框架之间的标准接口,以提高web应用在一系列web服务器间的移植性。

详细的说:

  1. WSGI是一套接口标准协议/规范;
  2. 是作用在Web服务器和Python Web应用程序之间,用于通信;
  3. 目的是制定标准,以保证不同Web服务器可以和不同的Python程序之间相互通信

为什么需要wsgi呢?

当请求时Web服务器需要和web应用程序进行通信,但是web服务器有很多种啊,Python web应用开发框架也对应多种啊,所以WSGI应运而生,定义了一套通信标准。试想一下,如果不统一标准的话,就会存在Web框架和Web服务器数据无法匹配的情况,那么开发就会受到限制,这显然不合理的。

面试题二:描述一下django请求的生命周期?

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 1、用户请求进来先走到 wsgi 然后将请求交给 django的中间件
  • 2、穿过django中间件(方法是process_request) 路由匹配
  • 3、路由匹配成功之后就执行相应的 :视图函数
  • 4、在视图函数中可以调用orm做数据库操作
  • 5、根据模板文件 ,在后台进行模板渲染
  • 6、模板渲染完成之后就响应结果,再把这个响应结果经过所有中间件(方法:process_response) 和wsgi 返回给用户

面试题三:谈谈django的orm优化操作

  • 1、尽可能的使用only与defer:Defer方法的用途是查询数据库时跳过指定的字段,only方法是指定需要载入的字段。从而节省空间。一行数据可能没啥关系,但数据很多时,节省的内存空间不可忽视。

  • 2、select_related和prefetch_related都是做连表查询的:prefetch_related是查询了每个表,然后在语言层面进行连接,而select_related是通过join方法进行数据库的连接,所以select_related在查询的时候是比prefetch_related效率要高的,但是prefetch_related可以进行多对多的查询。
    总结:可以理解为外键使用select_related,多对多使用prefetch_related。

  • 3、在任何位置使用QuerySet.exists()或者QuerySet.count()都会导致额外的查询。

  • 4、不要做无所谓的排序,排序并非没有代价,每个排序的字段都是数据库必须执行的操作。

  • 5、如果要插入多条数据,则使用bulk_create来批量插入,减少sql执行的数量。

  • 6、使用QuerySet.Iterator迭代大数据,要么使用分页。

  • 7、复杂的查询(子查询),尽量采用原生SQL查询。

# 一、原生SQL --->  connectionfrom django.db import connection, connections
cursor = connection.cursor()  # cursor = connections['default'].cursor()
cursor.execute("""SELECT * from auth_user where id = %s""", [1])
row = cursor.fetchone() # fetchall()/fetchmany(..)# 二、extra
def extra(self, select=None, where=None, params=None, tables=None, order_by=None, 
select_params=None)# 构造额外的查询条件或者映射,如:子查询Entry.objects.extra(select={'new_id': "select col from sometable where othercol > %s"},select_params=(1,))Entry.objects.extra(where=['headline=%s'], params=['Lennon'])Entry.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'"])Entry.objects.extra(select={'new_id': "select id from tb where id > %s"}, select_params=(1,), order_by=['-nid'])# 三、 raw函数
def raw(self, raw_query, params=None, translations=None, using=None):# 执行原生SQLmodels.UserInfo.objects.raw('select * from userinfo')# 如果SQL是其他表时,必须将名字设置为当前UserInfo对象的主键列名models.UserInfo.objects.raw('select id as nid,name as title  from 其他表')# 为原生SQL设置参数models.UserInfo.objects.raw('select id as nid from userinfo where nid>%s', params=[12,])# 将获取的到列名转换为指定列名name_map = {'first': 'first_name', 'last': 'last_name', 'bd': 'birth_date', 'pk': 'id'}Person.objects.raw('SELECT * FROM some_other_table', translations=name_map)# 指定数据库models.UserInfo.objects.raw('select * from userinfo', using="default")

面试题四:列举django中间件的5个方法?以及django中间件的应用场景?

process_request(self,request)  先走request 通过路由匹配返回
process_view(self, request, callback, callback_args, callback_kwargs) 再返回执行view
process_template_response(self,request,response)   当视图函数的返回值,process_template_response是在视图函数执行完成后立即执行,但是它有一个前提条件,那就是视图函数返回的对象有一个render()方法
process_exception(self, request, exception)  这个方法只有在视图函数中出现异常了才执行,它返回的值可以是一个None也可以是一个HttpResponse对象。
process_response(self, request, response)

在这里插入图片描述

面试题五:django中如何实现orm表中添加数据时创建一条日志记录?

Django 中的一些常用内置信号。与Model 相关的信号,这些信号由各个 Model 的方法发送,如 save、__init__等,且通常都是成对出现的,如下所示:

  • django.db.models.signals.pre_init 与 django.db.models.signals.post_init:实例化模型之前与之后发送的信号,即在__init__方法执行的前后。
  • django.db.models.signals.pre_save 与 django.db.models.signals.post_save:模型实例保存(执行save方法)前后发送的信号。
  • django.db.models.signals.pre_delete 与 django.db.models.signals.post_delete:模型实例或 QuerySet 的 delete() 方法执行前后发送的信号。
  • django.db.models.signals.m2m_changed:模型实例中的ManyToManyField(多对多)字段被修改(add,remove,clear)的前后发送的信号。

面试题六:django缓存如何设置?

django中提供了5种缓存后端:

  • 内存
  • 文件
  • 数据库
  • Memcache缓存(python-memcached模块)

安装第三方组件支持redis:

  • django-redis组件

只需要修改django项目的配置文件settings.py,即可实现不同缓存方式的切换。

#  一、内存CACHES = {'default': {'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',  # 指定缓存使用的引擎'LOCATION': 'unique-snowflake',  # 写在内存中的变量的唯一值 'TIMEOUT': 300,  # 缓存超时时间(默认为300秒,None表示永不过期)'OPTIONS': {'MAX_ENTRIES': 300,  # 最大缓存记录的数量(默认300)'CULL_FREQUENCY': 3,  # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3)}}# 二、文件缓存CACHES = {'default': {'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',  # 指定缓存使用的引擎'LOCATION': '/var/tmp/django_cache',  # 指定缓存的路径'TIMEOUT': 300,  # 缓存超时时间(默认为300秒,None表示永不过期)'OPTIONS': {'MAX_ENTRIES': 300,  # 最大缓存记录的数量(默认300)'CULL_FREQUENCY': 3,  # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3)}}
}
# 三、数据库缓存
CACHES = {'default': {'BACKEND': 'django.core.cache.backends.db.DatabaseCache',  # 指定缓存使用的引擎'LOCATION': 'cache_table',  # 数据库表  'OPTIONS': {'MAX_ENTRIES': 300,  # 最大缓存记录的数量(默认300)'CULL_FREQUENCY': 3,  # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3)}}
}# python manage.py createcachetable 创建缓存表
# 四、Memcached缓存# Memcached是Django原生支持的缓存系统.要使用Memcached,需要下载Memcached的支持库python-memcached或pylibmc.CACHES = {'default': {'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',  # 指定缓存使用的引擎'LOCATION': '192.168.10.100:11211',  # 指定Memcache缓存服务器的IP地址和端口'OPTIONS': {'MAX_ENTRIES': 300,  # 最大缓存记录的数量(默认300)'CULL_FREQUENCY': 3,  # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3)}}
}
# 五、 Redis缓存
CACHES = {"default": {"BACKEND": "django_redis.cache.RedisCache", # 缓存类型"LOCATION": "127.0.0.1:6379", # ip端口"OPTIONS": {"CLIENT_CLASS": "django_redis.client.DefaultClient",  #"CONNECTION_POOL_KWARGS": {"max_connections": 100} # 连接池最大连接数# "PASSWORD": "密码",}}
}

使用缓存的五种情况

第一:全站使用缓存,用户的请求通过中间件,经过一系列的认证等操作,如果请求的内容在缓存中存在,则使用FetchFromCacheMiddleware获取内容并返回给用户# 当返回给用户之前,判断缓存中是否已经存在,如果不存在,则UpdateCacheMiddleware会将缓存保存至Django的缓存之中,以实现全站缓存# 请求来了,是从上到下入走中间件;响应的时候是从下到上走中间件。因此,获取页面放在最后,保存页面放最前面

MIDDLEWARE = ['django.middleware.cache.UpdateCacheMiddleware',  # 响应HttpResponse中设置几个headers'django.middleware.security.SecurityMiddleware','django.contrib.sessions.middleware.SessionMiddleware','django.middleware.common.CommonMiddleware','django.middleware.csrf.CsrfViewMiddleware','django.contrib.auth.middleware.AuthenticationMiddleware','django.contrib.messages.middleware.MessageMiddleware','django.middleware.clickjacking.XFrameOptionsMiddleware','django.middleware.cache.FetchFromCacheMiddleware',  # 用来缓存通过GET和HEAD方法获取的状态码为200的响应
]CACHE__MIDDLEWARE_SECONDS=15  # 设定超时时间为15秒

第二:视图中使用缓存,视图缓存是将视图函数执行过程中生成缓存数据,主要以装饰器的形式来实现。装饰器有三个参数:timeout、cache和#key_prefix,参数timeout是必选参数,其余两个是可选参数。

from django.shortcuts import render 
from django.views.decorators.cache import cache_page
# cache与全站缓存CACHE_MIDDLEWARE_ALIAS相同# key_prefix与全站缓存CACHE_MIDDLEWARE_KEY_PREFIX相同
@cache_page(10, cache='default', key_prefix='mysite')
def index(request):return render(request,"index.html")

第三:路由缓存,作用与视图缓存相同,但两者是有区别的。如有两个URL同时指向一个视图函数,分别访问这两个URL时,路由缓存会判断URL是否生成缓存而决定是否执行视图函数。

from django.conf.urls import url
from app1 import views
from django.views.decorators.cache import cache_pageurlpatterns = [url(r'^index/', cache_page(10,cache='default', key_prefix='mysite')(views.index)),

第四:模板页面缓存
对模板某部分的数据设置缓存,常用于模板内容变动较少的情况。通过Django的缓存标签实现的,缓存标签只支持两个参数:timeout和key_prefix,以index.html为例实现模板缓存
在这里插入图片描述
将按给定的时间缓存包含块中的内容。它最少需要两个参数:缓存时间(以秒为单位);给缓存片段起的名称,该名称将被视为是字符串,而不是变量。设定超时时间为10秒, 给缓存模板片段起名为 “time”
在这里插入图片描述

第五:手动缓存
如果不想为一个方法(页面)进行缓存,只想缓存某个字段的话,可以 手动缓存

from django.core.cache import cache
from django.http.response import HttpResponse
import timedef index(request):print('视图函数被调用')result = cache.get('result')if not result:result = 0for i in range(10):result += itime.sleep(0.5)cache.set('result', result, 10)ctime = time.strftime('%H:%M:%S', time.localtime())return HttpResponse("时间{}的结果是:{}".format(ctime, result))

面试题七:对cookies与session的了解?他们能单独用吗?

session与cookies最核心区别在于额外信息由谁来维护

  • 利用cookies来实现会话管理时,用户的相关信息或者其他我们想要保持在每个请求中的信息,都是放在cookies中,而cookies是由客户端来保存,每当客户端发出新请求时,就会稍带上cookies,服务端会根据其中的信息进行操作。
  • 当利用session来进行会话管理时,客户端实际上只存了一个由服务端发送的session_id,而由这个session_id,可以在服务端还原出所需要的所有状态信息,从这里可以看出这部分信息是由服务端来维护的。

因为Session是用Session ID来确定当前对话所对应的服务器Session,而Session ID是通过Cookie来传递的,禁用Cookie相当于SessionID,也就得不到Session。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com