Django中日期字段查询与实例访问语法差异原因咨询
Django中查询语法与实例属性访问语法差异的原因
在Django中,你遇到的两种语法差异本质是因为它们服务于完全不同的场景:
1. ORM查询时的__year是数据库查询专属语法
当你使用Question.objects.get(pub_date__year=current_year)时,双下划线__是Django ORM的查询表达式约定,它的作用是告诉Django如何生成对应的SQL语句:
>>> Question.objects.get(pub_date__year=current_year) <Question: What's up?>
这个语法会被Django转换成类似WHERE EXTRACT(YEAR FROM pub_date) = %s的SQL过滤条件,让数据库直接在查询阶段完成年份筛选,属于ORM层与数据库交互的特殊规则。
2. 实例属性访问用.year是Python对象的通用语法
当你获取到q这个Question实例后,q.pub_date是一个标准的Python datetime(或date)对象,这类对象本身就提供了.year属性来获取年份,这是Python访问对象属性的标准方式:
In [56]: q=Question.objects.get(pub_date__year=current_year) In [57]: q.pub_date__year --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) Cell In [57], line 1 ----> 1 q.pub_date__year AttributeError: 'Question' object has no attribute 'pub_date__year' In [58]: q.pub_date.year Out[58]: 2023
pub_date__year并不是Question实例或其pub_date属性的有效名称,自然会触发AttributeError。
简单来说:前者是Django ORM向数据库发送查询的专用语法,后者是Python访问对象属性的通用规则,两者应用场景不同,语法规则自然不一样。
内容的提问来源于stack exchange,提问作者Ariel C
相关产品推荐
相关产品推荐

