python - Django反向外键
问题描述
我现在使用 python/django 1 个月了,我需要帮助,因为我找不到任何具有我正在寻找的答案的类似问题。我有工人模型和工作模型。一个工人可以有很多工作。我需要查询 Worker 的最新工作。
class Worker(models.Model):
name = models.CharField(max_length=128)
class Job(models.Model):
worker = models.ForeignKey(Worker)
type = models.CharField(max_length=64)
position = models.CharField(max_length=64)
location = models.CharField(max_length=128)
start_date = models.DateField()
我目前正在使用这个示例代码。问题是这会返回类似的 Worker 对象,包括它以前的作业。我只想用最新的工作地点和开始日期查询 Worker。
for employee in Job.objects.all():
print(employee.worker, employee.location, employee.start_date)
样本输出
(A, north, 2018-01-21)
(A, south, 2018-09-13)
(A, east, 2019-05-11)
(B, west, 2019-01-01)
有没有办法使用 for 循环来查询像Worker.job_set.all()
这样的预期输出
(A, east, 2019-05-11)
(B, west, 2019-01-01)
希望你能帮助像我这样的新手。先感谢您!:)
解决方案
我认为其他两个答案非常简单。他们俩都在解决您现在要解决的问题,但是一旦您拥有越来越多的工人/工作,这些解决方案就会失败,因为他们的所有解决方案都是 O(N*N)。这个解决方案是 O(N)。
subqry = models.Subquery(Job.objects.filter(worker_id=models.OuterRef('worker_id'))
.order_by('-start_date').values('id')[:1])
workers = Worker.objects.prefetch_related(models.Prefetch('job_set',
queryset=Job.objects.filter(id__in=subqry)))
for worker in workers:
# no matter what this will always have 1 // or nothing, depending on your logic; if nothing, fix this.
latest_job = list(worker.job_set.all())[0]
print(worker.name, latest_job.location, latest_job.start_date)
这将对Worker
其他工作进行一次查询,但只会对最新作业进行一次查询,其他解决方案将对每个工作人员进行查询,这是低效且缓慢的。
有关我如何测试所有这些的更多背景信息,请参阅此示例。https://gist.github.com/kingbuzzman/ac2ada9c27196fc90c1b75f2d01a6271#file-django_prefetch_limit-py-L163
推荐阅读
- python - Python - 从 UDP 服务器检索数据
- clojure - 如何在第一个真正的谓词匹配的嵌套地图上退出 Clojure walk postwalk?
- python - 如何将 Unicode 转换为 ASCII 忽略不可转换的字符?
- node.js - socket 和 express 如何在同一个端口上监听
- python - VSCode Python + OpenCV 路径不工作 [Windows]
- r - 如何在具有各自行/列索引的矩阵中找到 n 最小值
- javascript - 过滤器和映射对正确数量的组件做出反应但错误
- javascript - 如何避免从 webpack 中的块加载?[角度] [内联 js]
- python - 如何加快 numpy / pandas 中的成对操作
- javascript - 如何生成随机批量跟踪号?