【问题标题】:Improving the Django Query改进 Django 查询
【发布时间】:2016-11-03 10:16:23
【问题描述】:

我正在尝试优化以下 Django 视图。

def test_view(request, username):
  msgs = MyModel.objects.filter(name=username,
                                  created_at__range=[start_date, end_date]).order_by('-id')
  arr = []
  for msg in msgs:
    c = TestModel.objects.get(id=msg.test_id)
    if c not in arr:
        arr.append(c)

return render(request, "test.html", {'context': arr})

所以我有两个模型。

  • 我的模特
  • 测试模型

目标:

  • 仅从MyModel 中获取名为test_id 的列上的唯一值,该列由idMyModel 排序。
  • 只需要来自MyModel 的两个参数。他们是test_idcreated_at

目前我可以看到以下改进方法。

  • 使用过滤器查询中的值仅获取 test_id 和 created_at。
  • 在 Django 中使用 mysql Distinct 关键字对 test_id 进行唯一搜索
  • 不必要地循环遍历数据查询集。
  • 再次在 arr 中搜索集合似乎真的没有必要且耗时。

我对 Django 比较陌生。因此,对于我应该如何继续或我应该阅读的任何链接的任何帮助将不胜感激。

【问题讨论】:

  • 你应该总结一下你的视图在做什么。例如,我不明白您为什么在循环中设置 c.user_namec.last_time,尤其是当您不保存任何内容时。
  • 什么是collection?你的代码中只是c吗?
  • 请展示您的模型。你的意思是写TestModel.objects.get(test_id=msg.test_id)?像msgsTestModel 这样混合真实和虚构的变量名会让你的问题变得混乱。
  • 您需要获取哪些 id/created_at 值 - 来自 MyModel 或 TestModel?

标签: python mysql sql django


【解决方案1】:

我建议修改您的视图如下:

def test_view(request, username):
    msgs = MyModel.objects.filter(
        name=username, created_at__range=[start_date, end_date]
    ).order_by('-id').values_list('test_id', flat=True)

    arr = TestModel.objects.filter(id__in=msgs)

    return render(request, "test.html", {'context': arr})

这样您就可以避免在一个查询中获取您需要的所有 TestModel。此外,在 MyModel 查询中使用 values_list 可以节省内存,因为您除了 test_id 之外什么都不使用。

【讨论】:

    猜你喜欢
    • 2016-02-04
    • 1970-01-01
    • 2018-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多