文章目录
整体结构
1.MVC模式理解, 如何使用
*引自MVC模式
优点:
- 可以为一个模型在运行的同时建立和使用多个视图
- 视图与控制器的可插拔性
- 模型的可移植性
- 潜在的框架结构
缺点:
- 增加了系统结构和实现的复杂性
- 视图与控制器连接过于紧密
- 视图对模型数据的低效率访问
- 高级界面工具不支持MVC模式
django框架中的MVC实现:
当URL被请求 ➜ 调用指定的Python方法 ➜ 通过业务逻辑(model)处理 ➜ 经过模板(template) ➜ 呈现页面(view)
2.如何理解MTV
3.Django你熟悉的模块都有哪些?分别作用
- Model 抽象出数据模型类,规定字段类型,定义模型内置方法
- serializers 序列化、反序列化model数据,请求字段校验
- signal, 信号处理,某个任务完成或达到指定状态时执行指定函数
- View,指定如何处理请求和如何处理网页
- template,页面函数输出页面相应
- middleware, 中间件,修改request或response的钩子
- cache, 缓存,分数据缓存,文件缓存、单视图缓存、局部视图缓存、全站缓存
- form, 内置表单
- log,日志
- admin, 后台
- manage, app启动文件
- wsgi,
4.wsgi
定义:wsgi(Web Server Gateway Interface), Web服务器网关接口,是为python语言定义的Web服务器与Web应用程序或框架之间的一种简单而通用的接口。 简单来说就是web Server与web application之间通信的协议
协议内容:
- server负责从客户端接收请求,将request转发给应用,再将应用返回的response返回给服务端
- application接收server转发的request
model层
1.如何理解Django Migrations的作用
作用:Django框架提供的migrations是一个独立的机制,主要用以在Django应用中的model类和数据库结构的schema之间进行同步
文件:
- miagrations在Django应用中是一系列文件,位于Django应用的migrations目录下,用以存储Django应用中的model类的变化。
- 每次在Django应用中对model类的修改,都会对应一个migration文件。
- 一个migration文件与数据库结构的schema的一个版本对应。
- 从文件名看,migrations文件也是Python软件模块,其中包含各种用以操作数据库的django.db.migrations.operations对象。
相关命令
- makemigrations
- migrate
- sqlmigrate
- showmigrations
2.介绍下ORM下的N+1问题,发生的原因,以及解决方案。
发生原因
N+1是orm中比较经典的问题, 一般出现在一对多查询中,关联查询时,对一个表的n条查询结果进行遍历取关联表的字段, 执行的sql语句就是n+1条
影响
不断对数据库提交sql请求会影响性能
解决方案
- 可以使用select_related方法来查询
- 可以使用缓存,第一次查询是n+1,再次查询时速度会快
- 原生sql语句
示例
from django.db import models
class User(models.Model):
name = models.CharField(max_length=255)
class Post(models.Model):
owner = models.ForeignKey(User) # by the5fire
title = models.CharField(max_length=255)
content = models.TextField()
# 文章列表页,查询文章与用户
# 普通方法
posts = Post.objects.all() # 获取所有的文章数据,注意此时不会执行sql语句 by the5fire
result = []
for post in posts: # 此时会执行select * from post的查询
result.append({
'title': post.title,
'owner': post.owner.name, # 此时会执行 select * from user where user_id = <post.user_id>
})
# sql
SELECT t1.title, t2.name from post as t1 INNER JOIN user as t2 ON t2.id = t1.owner_id;
# select_related
posts_with_user = Post.objects.all().select_related('user)
3.meta常用配置项
ordering 排序字段
abstract 是否为抽象类,抽象类可被继承
db_table 指定自定义数据库表名
unique_together 当需要通过两个字段保持唯一性时使用
verbose_name 为模型类起一个可读的名字
verbose_name_plural 指定模型复数形式是什么 不指定Django会自动在模型名称后加一个's'
4.QuerySet作用,常用QuerySet优化措施
QuerySet作用:
- QuerySet 可以被构造,过滤,切片,做为参数传递,这些行为都不会对数据库进行操作。只要你查询的时候才真正的操作数据库。
- 可以遍历,序列化、缓存、API查询
QuerySet特点:
- QuerySet对象类似于python中的list,有list对象的切片、遍历等方法, 也有内置的其他方法。如count()
- QuerySet是延迟获取的,只有当用到这个QuerySet时,才会查询数据库求值
- 查询到的QuerySet又是缓存的,当再次使用同一个QuerySet时,并不会再查询数据库,而是直接从缓存获取(不过,有一些特殊情况)。
- 一般而言,当对一个没有求值的QuerySet进行的运算,返回的是QuerySet、ValuesQuerySet、ValuesListQuerySet、Model实例时,一般不会立即查询数据库;反之,当返回的不是这些类型时,会查询数据库。
优化:
- 避免读取全部数据,优先使用exists,count,only,defer,切片等
- 使用Iterator()迭代大数据
- 判断存在使用exists
- 使用values或values_list获取部分需要的表字段
- 外键关联过多可使用select_related提前将关联表join
- 使用数据库索引
- 使用正确的字段类型
5.manager作用,如何定制?什么情况下需要定制
作用 :
-
manager是django模型中的管理器,用于提供数据库查询操作的接口,django的每个model至少存在一个manager
-
Manager定义表级方法(表级方法就是影响一条或多条记录的方法)
如何定制
以models.Manager为父类,定义自己的manager,增加表级方法
自定义 Manager
额外添加 Manager
方法和/或修改初始值 QuerySet
这个 Manager
返回
示例
自定义manager提供with_counts()方法, 返回所有OpinionPoll对象,且每个对象均有num_responses属性
from django.db import models
class PollManager(models.Manager):
def with_counts(self):
from django.db import connection
with connection.cursor() as cursor:
cursor.execute("""
SELECT p.id, p.question, p.poll_date, COUNT(*)
FROM polls_opinionpoll p, polls_response r
WHERE p.id = r.poll_id
GROUP BY p.id, p.question, p.poll_date
ORDER BY p.poll_date DESC""")
result_list = []
for row in cursor.fetchall():
p = self.model(id=row[0], question=row[1], poll_date=row[2])
p.num_responses = row[3]
result_list.append(p)
return result_list
class OpinionPoll(models.Model):
question = models.CharField(max_length=200)
poll_date = models.DateField()
objects = PollManager()
也可以为一个model添加多个manager管理器来实现过滤器的效果
6.raw sql与ORM效率对比?
先了解下ORM的优缺点, 在项目中根据需要合理的使用ORM语法与原生sql。
优点:
- 快速开发,更多精力放在业务而非数据库
- 方便统一编码风格与后期维护,避免人为bug。隐藏了数据访问细节,使通用数据库交互变得简单
- 方便数据库迁移,迁移新的数据库时不需要修改对象模型,只需修改数据库配置
- 同时连接多个数据库并切换执行增删改查操作
缺点:
- 性能问题
- 自动化进行数据库关系映射需要消耗系统资源
- 多表联查,条件复杂查询时可能会生成效率低下的SQL
- sql调优; sql语句由ORM框架生成,虽减少语句错误的发生,但也给sql调优带来困难
- 越是功能强大的ORM越消耗内存, 一个ORM Object会带有很多成员变量和成员函数
一般来说ORM足以满足需求,但如果对性能要求特别高或查询十分复杂,可以考虑原生sql与ORM共用
7. Django内置提供的权限逻辑是什么,以及其粒度?
Django内置的权限系统包括以下三部分:
- 用户
- 许可 Permission
- 组 Groups
超级用户可以查看所有页面
普通用户可查看的页面受权限限制
权限粒度
- 粗粒度权限管理,对资源类型的权限管理,如菜单,url,用户添加页面,用户信息,类方法,页面按钮等
- 细粒度权限管理就是数据级别的权限管理
Django自带的权限系统属于粗粒度权限管理,当它无法满足需求时,需要引入另一种更细的权限机制:对象权限(object permission)
Object Permission是一种对象颗粒度上的权限机制,它允许为每个具体对象授权。仍沿用最开始的例子,如果model B有三个实例 B1,B2 和B3,如果我们把B1的可写权限赋予用户A,则A可以修改B1对象,而对B2,B3无法修改。
对group也一样,如果将B2的可写权限赋予group C,则隶属于group C的所有用户均可以修改B2,但无法修改B1和B3。结合Django自带权限机制和object permission,博客系统中作者的权限控制迎刃而解:系统全局上不允许作者编辑文章,而对于属于作者的具体文章,赋予编辑权限即可。
Django其实包含了object permission的框架,但没有具体实现,object permission的实现需要借助第三方app django-guardian,我们在开发中用调用django guradian封装好的方法即可。