开发者

Django中get()与filter()的区别及常见错误

目录
  • 1. 核心区别
  • 2. 语法与示例
    • get()的用法
    • filter()的用法
  • 3. 性能对比
    • 4. 适用场景
      • 推荐使用get()的场景
      • 推荐使用filter()的场景
    • 5. 常见错误案例
      • 错误使用get()的场景
      • 低效的filter()使用
    • 6. 总结

      在 Django 中,get()filter() 是 QuerySet API 中用于检索数据的两个核心方法,它们的功能和使用场景有明显区别。以下是详细对比:

      1. 核心区别

      特性get()filter()
      返回值单个对象(模型实例)查询集(QuerySet,可迭代)
      数量限制必须精确匹配1个对象可以匹配0个、1个或多个对象
      对象不存在时抛出 DoesNotExist 异常返回空查询集(不报错)
      多对象匹配时抛出 MultipleObjectsReturned 异常返回包含多个对象的查询集
      链式调用不支持(返回的是模型实例)支持(可继续添加过滤条件)

      2. 语法与示例

      get()的用法

      # 获取 ID 为 1 的书(必须存在且唯http://www.devze.com一)
      book = Book.objects.get(id=1)
      
      # 等价的手动异常处理
      try:
          book = Book.objects.get(id=1)
      except Book.DoesNotExist:
          # 处理不存在的情况
          pass
      except Book.MultipleObjectsReturned:
          # 处理多对象匹配的情况
          pass
      

      filter()的用法

      # 获取所有已发布的书(可能有0本或多本)
      books = Book.objects.filter(status='published')
      
      # 链式过滤:获取已发布且价格大于 50 的书
      books = Book.objects.filter(status='published').filter(price__gt=50)
      
      # 等价的单语句写法
      books = Book.objects.filter(status='published', price__gt=50)
      
      # 获取第一本书或 None(推荐替代 get() 的安全写法)
      first_book = books.first()  # 等价于 books[0] if books else None
      

      3. 性能对比

      • get():直接查询单条记录,生成的 SQL 类似 SELECT ... WHERE ... pythonLIMIT 1,理论上更高效。
      • filter().first():生成的 SQL 是 SELECT ... WHERE ... LIMIT 1,与 get() 几乎相同,但多了一步 python 对象转换,性能损耗可忽略不计。

      注意:在查询条件唯一(如主键查询)时,两者性能接近;但 filter().first() 更安全。

      4. 适用场景

      推荐使用get()的场景

      • 查询条件唯一(如通过主键或唯一键查询)。
      • 对象必须存在,否则视为程序错误(如配置项、固定ID的系统数据)。
      • 示例
        user = User.objects.get(username='admin')  # 管理员用户必须存在
        

      推荐php使用filter()的场景

      • 查询条件不唯一(如按类别筛选商品)。
      • 结果可能js为空(如搜索功能)。
      • 需要链式查询(如分页、排序、多条件组合)。
      • 示例
        # 搜索功能(结果可能为空)
        books = Book.objects.filter(title__icontains='python')
        
        # 分页查询
        books = Book.objects.filter(category='tech').order_by('-pub_date')[:10]
        

      5. 常见错误案例

      错误使用get()的场景

      # 错误:title 可能不唯一,导致 MultipleObjectsReturned
      book = Book.objects.get(title="Python")
      
      # 正确:使用 filter().first()
      book = Book.objects.filter(title="Python").first()
      

      低效的filter()使用

      # 低效:两次数据库查询
      if Book.objects.filter(id=1).exists():
          book = Book.objects.get(id=1)  # 重复查询
      
      # 高效:单次查询
      book = Book.objects.filter(id=1).first()
      

      6. 总结

      场景方法
      通过主键/唯一键获取单个对象get()(需确保存在)
      安全获取单个对象(不存在时返回 None)filter().first()
      查询可能存在多个结果或空结果filter()
      需要链式查询(如分页、排序)filter()

      建议:优先使用 filter().first() 替代 get(),除非你能绝对保证查询条件的唯一性和存在性。

      到此这篇关于Django中get()与filter()的区别及常见错误的文章就介绍到这了,更多相关DjangoveWnYhYbp中get()与filter()内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

      0

      上一篇:

      下一篇:

      精彩评论

      暂无评论...
      验证码 换一张
      取 消

      最新开发

      开发排行榜