关于Django,这9点提升技能的技巧你必须知道
itomcoil 2024-12-31 12:23 32 浏览
Django 是一个用于构建Web应用程序的高层次Python Web框架。它遵循”Model-View-Template” (MVT)的设计模式,旨在让Web开发更快速、简便,并且鼓励开发者采用”干净、可复用、快速开发”的原则。Django 由经验丰富的开发人员开发,提供了一套完整的工具和功能,帮助开发者快速构建高效、可扩展的Web应用程序。
在今天的文章中,我想分享一些Django中的开发小技巧,这些技巧虽然不像那些耀眼的“标志性”功能那样备受关注,但其中的一些技巧却能在我们日常编码中带来极大的改变。
技巧 1:内置 QuerySet 方法
除了极为常见的 filter()、exclude() 和 annotate() 方法外,Django 还提供了其他鲜为人知的方法,如 first() 和 last(),作为语法糖来帮助保持代码的可读性。
顾名思义,first() 返回 QuerySet 中的第一条记录,而 last() 则返回最后一条记录。我个人倾向于在单元测试中使用这些函数。
例如,请看下面的代码,它抓取了 ‘Fruit’ 中的第一条记录:
同样的代码可以转换为使用 first() 方法:
你可以发现,代码的可读性大大提高了。除此之外,使用 first() 和 last() 方法的另一个好处是,如果 QuerySet 为空,它们会返回一个 None 对象,而切片方法则需要更多的异常处理:
技巧 2:get_or_create 和 create_or_update
我经常使用的另外两个非常有用的 QuerySet 方法是 get_or_create() 和 create_or_update()。
在这两种情况下,这些方法都可以节省大量模板代码,同时还能提高代码的可读性:
这两种方法都会返回一个(record, bool)元组,其中第一项是相关记录,如果操作导致创建了记录,则第二项为 True。
一个使用 create_or_update() 的类似示例:
在这里,整个 try-except 子句再次简化为一个方法调用,它返回一个(record, bool)元组,其功能与上一个示例完全相同。
技巧 3:模板中的 get_FOO_display
在使用定义了选择属性字段的 Django 模型时,我经常希望在模板中打印出该字段的用户友好值。例如,给定以下模型:
在使用该模型的模板中,我想打印一本书的状态,但使用 {{book.status}} 会打印一个无用的整数,即 2。但如果我们用下面的代码:
结果显示如下 HTML:
技巧 4:批量创建和更新(Bulk creates and updates)
Django 中的批量创建和更新功能强大,这不仅是因为它们非常易于使用,使代码的阅读更加轻松,还因为整个操作都是以原子方式完成的。所谓原子方式,指的是在数据库操作中,一个事务(即一组相关操作)会被视为一个单一的整体。在原子操作中,不可能出现中间状态:要么所有的更改都应用到数据库中,要么如果发生错误,数据库会回滚到操作开始前的状态,就像什么都没有发生过一样。
在 Django 中进行批量创建非常简单 -- 实例化一个包含所有要创建的模型记录的列表,然后将其输入 bulk_create() 方法,如下所示:
同时,可以使用查询集进行批量更新:
返回的整数表示更新的记录数。
技巧 5:auto_now 和 auto_now_add
Django 为字段提供了两个非常有用的属性,可以帮助我们管理日期:auto_now 和 auto_now_add
每次更新记录时,auto_now 都会将字段设置为当前日期,而 auto_now_add 只在创建记录时才设置字段的值。
示例:
观察这个模型的运行,注意到 last_modified 字段被更新了,但 created_on 字段没有更新:
技巧 6:有用的单元测试断言方法
在 Django 中,单元测试是确保你的代码按预期运行的重要工具之一。Django 提供了一个基于 Python 标准库 unittest 模块的测试框架,其中包含了各种断言方法。
什么是断言方法?
断言方法是测试中的关键部分,用于验证某个条件是否为真。如果断言通过,则测试继续执行;如果断言失败,测试就会中断并报告错误。断言通常是测试用例的核心,因为它们判断代码是否按照期望的方式工作。
常用的 Django 单元测试断言方法
Django 的断言方法大部分来自 unittest,以下是一些常用的断言方法以及它们的具体用途:
1. assertEqual(a, b) 和 assertNotEqual(a, b)
? 作用: 检查两个值是否相等(或不等)。
在这行代码中,断言 response.status_code 是否等于 200,即检查页面请求是否成功。
2. assertTrue(x) 和 assertFalse(x)
? 作用: 检查某个条件是否为真(或假)。
断言 user.is_active 为真,确保用户是激活状态。
3. assertRaises(exception, callable, *args, **kwargs)
? 作用: 检查某个代码块是否抛出了指定的异常。
断言 int('invalid') 会抛出 ValueError,用于验证函数的错误处理是否正确。
4. assertRedirects(response, expected_url)
? 作用: 检查响应是否导致了重定向到预期的 URL。
检查响应是否重定向到 /login/,通常用于测试某些视图的重定向行为。
除此之外,还有很多其他的断言方法,感兴趣的读者可以自行了解,这里不再一一列举。
技巧 7:鲜为人知的模板标签
Django 提供了一些非常有用的标签。下面我将重点介绍一些不太常见但仍然非常有用的标记:
- join 的功能与 Python 的字符串 join 方法完全相同。
- first 和 last 返回给定列表中的相应值。
- floatformat 控制在小数点后显示多少位数字,对于显示价格值非常有用(例如: {{ price|floatformat:2 }})
- intcomma 为大于 1000 的数字添加逗号,以便于阅读,例如 1000000 变成 1,000,000
- linebreaksbr 自动将换行符转换为HTML 实体。
- urlize 自动将 URL 字符串转换为指向同一 URL 的锚标签。
- yesno 将布尔值转换为用户可读的字符串,例如{{ record.is_active|yesno: "Active,Disabled" }} 将把 True 值转换为字符串 Active,把 False 值转换为 Disabled。
模板标记和过滤器的完整列表可以参考官方文档:https://docs.djangoproject.com/en/5.0/ref/templates/builtins/
技巧 8:refresh_from_db
在 Django 中,当你对一个模型实例进行操作时,比如对某个字段进行修改、保存等操作,模型实例的状态会在内存中保持。但是,如果在某个时刻数据库中的数据被其他进程或请求修改了,而你仍然使用旧的内存实例,这可能导致你操作的是过时的数据。
refresh_from_db() 方法解决了这个问题。它强制 Django 重新从数据库加载模型实例的数据,从而确保你操作的是数据库中的最新版本。
场景举例
假设你在程序的一部分读取了一个用户实例 user,并在操作它的时候,数据库中的该用户被其他地方修改了。如果你想确保你的实例包含数据库中的最新数据,可以调用 refresh_from_db():
在这个例子中,refresh_from_db() 保证了你获取的是最新的数据,而不是操作之前获取的、可能已经过时的版本。
技巧 9:Admin register decorator
在这段代码中,展示了两种向 Django admin 注册模型的方式:一种是不使用装饰器,另一种是使用装饰器。从中可以看出,使用装饰器的方式更为简洁,而不使用装饰器的方式可能更适合于更复杂的注册逻辑。
我很难将 Django 中最常用的编码快捷方式缩减到十种,因为好的快捷方式实在太多了!最后,我选择了我最常用的,以及为我节省了最多模板代码的技巧进行分享。如果你们还有想了解的编码技巧或窍门,可以在下方留言!
- 上一篇:如何建立第一个Django工程
- 下一篇:Django开发常用方法及面试题
相关推荐
- selenium(WEB自动化工具)
-
定义解释Selenium是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE(7,8,9,10,11),MozillaF...
- 开发利器丨如何使用ELK设计微服务中的日志收集方案?
-
【摘要】微服务各个组件的相关实践会涉及到工具,本文将会介绍微服务日常开发的一些利器,这些工具帮助我们构建更加健壮的微服务系统,并帮助排查解决微服务系统中的问题与性能瓶颈等。我们将重点介绍微服务架构中...
- 高并发系统设计:应对每秒数万QPS的架构策略
-
当面试官问及"如何应对每秒几万QPS(QueriesPerSecond)"时,大概率是想知道你对高并发系统设计的理解有多少。本文将深入探讨从基础设施到应用层面的解决方案。01、理解...
- 2025 年每个 JavaScript 开发者都应该了解的功能
-
大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发。1.Iteratorhelpers开发者...
- JavaScript Array 对象
-
Array对象Array对象用于在变量中存储多个值:varcars=["Saab","Volvo","BMW"];第一个数组元素的索引值为0,第二个索引值为1,以此类推。更多有...
- Gemini 2.5编程全球霸榜,谷歌重回AI王座,神秘模型曝光,奥特曼迎战
-
刚刚,Gemini2.5Pro编程登顶,6美元性价比碾压Claude3.7Sonnet。不仅如此,谷歌还暗藏着更强的编程模型Dragontail,这次是要彻底翻盘了。谷歌,彻底打了一场漂亮的翻...
- 动力节点最新JavaScript教程(高级篇),深入学习JavaScript
-
JavaScript是一种运行在浏览器中的解释型编程语言,它的解释器被称为JavaScript引擎,是浏览器的一部分,JavaScript广泛用于浏览器客户端编程,通常JavaScript脚本是通过嵌...
- 一文看懂Kiro,其 Spec工作流秒杀Cursor,可移植至Claude Code
-
当Cursor的“即兴编程”开始拖累项目质量,AWS新晋IDEKiro以Spec工作流打出“先规范后编码”的系统工程思维:需求-设计-任务三件套一次生成,文档与代码同步落地,复杂项目不...
- 「晚安·好梦」努力只能及格,拼命才能优秀
-
欢迎光临,浏览之前点击上面的音乐放松一下心情吧!喜欢的话给小编一个关注呀!Effortscanonlypass,anddesperatelycanbeexcellent.努力只能及格...
- JavaScript 中 some 与 every 方法的区别是什么?
-
大家好,很高兴又见面了,我是姜茶的编程笔记,我们一起学习前端相关领域技术,共同进步,也欢迎大家关注、点赞、收藏、转发,您的支持是我不断创作的动力在JavaScript中,Array.protot...
- 10个高效的Python爬虫框架,你用过几个?
-
小型爬虫需求,requests库+bs4库就能解决;大型爬虫数据,尤其涉及异步抓取、内容管理及后续扩展等功能时,就需要用到爬虫框架了。下面介绍了10个爬虫框架,大家可以学习使用!1.Scrapysc...
- 12个高效的Python爬虫框架,你用过几个?
-
实现爬虫技术的编程环境有很多种,Java、Python、C++等都可以用来爬虫。但很多人选择Python来写爬虫,为什么呢?因为Python确实很适合做爬虫,丰富的第三方库十分强大,简单几行代码便可实...
- pip3 install pyspider报错问题解决
-
运行如下命令报错:>>>pip3installpyspider观察上面的报错问题,需要安装pycurl。是到这个网址:http://www.lfd.uci.edu/~gohlke...
- PySpider框架的使用
-
PysiderPysider是一个国人用Python编写的、带有强大的WebUI的网络爬虫系统,它支持多种数据库、任务监控、项目管理、结果查看、URL去重等强大的功能。安装pip3inst...
- 「机器学习」神经网络的激活函数、并通过python实现激活函数
-
神经网络的激活函数、并通过python实现whatis激活函数感知机的网络结构如下:左图中,偏置b没有被画出来,如果要表示出b,可以像右图那样做。用数学式来表示感知机:上面这个数学式子可以被改写:...
- 一周热门
- 最近发表
- 标签列表
-
- ps图案在哪里 (33)
- super().__init__ (33)
- python 获取日期 (34)
- 0xa (36)
- super().__init__()详解 (33)
- python安装包在哪里找 (33)
- linux查看python版本信息 (35)
- python怎么改成中文 (35)
- php文件怎么在浏览器运行 (33)
- eval在python中的意思 (33)
- python安装opencv库 (35)
- python div (34)
- sticky css (33)
- python中random.randint()函数 (34)
- python去掉字符串中的指定字符 (33)
- python入门经典100题 (34)
- anaconda安装路径 (34)
- yield和return的区别 (33)
- 1到10的阶乘之和是多少 (35)
- python安装sklearn库 (33)
- dom和bom区别 (33)
- js 替换指定位置的字符 (33)
- python判断元素是否存在 (33)
- sorted key (33)
- shutil.copy() (33)