【问题标题】:Query with Django ORM (joining models?)使用 Django ORM 查询(加入模型?)
【发布时间】:2011-10-24 15:07:41
【问题描述】:

我有以下型号:

class Thread(models.Model):
    name = models.CharField(max_length=50)
    category = models.ForeignKey(Category)

class Post(models.Model):
    thread = models.ForeignKey(Thread)
    datetime = models.DateTimeField(auto_now_add=True)
    author = models.ForeignKey(User)

这是给我的论坛系统的。

我需要获取类别 X 的所有 Threads,并且我需要有一些自定义属性,例如帖子最后一篇帖子的 datetimepk,例如:

threads = Thread.objects.filter(category=x)
last_post = Post.objects.filter(thread=threads[0]).order_by('-pk')[0]

然后我想将所有内容转移到模板中,以便我得到:

{{ t.pk }} as thread_pk
{{ t.last_post_pk }} as last_post_pk

等等。

【问题讨论】:

    标签: django orm


    【解决方案1】:

    要获得每个线程的最后一篇文章,您应该使用聚合:

    Post.objects.filter(thread__in=threads).values('thread').annotate(last_id=Max('id')).order_by()
    

    这将从threads 的每个线程中获取last_id

    【讨论】:

      【解决方案2】:

      由于 Django 不会像您期望的 SQL 连接那样进行连接(请参阅我的评论以获得进一步的解释),我将在视图中解决它(或者可能是添加到 Thread 类的方法)。考虑以下示例视图:

      def index(request):
          res = []
          for t in Thread.objects.filter(category__name='x'):
              res.append((t, Post.objects.filter(thread=t).order_by('-datetime')[0]))
          # Optionally sort by datetime here:
          # res.sort(key=lambda x: x[1].datetime, reverse=True)
          return render_to_response('index.html', {'result': res})
      

      然后您可以在模板中使用它,如下所示:

      {% for r in res %}
          Thread {{ r.0.name }}, last post by {{ r.1.author.name }} on {{ r.1.datetime }}.
      {% endfor %}
      
      # This would give something like this:
      # Thread mythread, last post by john on Oct. 21, 2011, 1:52 a.m..
      

      通过创建一个由Threads 和Posts 组成的元组,您并没有真正加入它们,但可以让它们在模板中轻松可用。

      【讨论】:

      • 不确定不支持类似 SQL 的连接是什么意思...您的第 3 行可以写为 `Thread.objects.filter(category__name='x')'。出于优化原因避免某些连接完全是另一回事。
      • @BéresBotond:我的意思是 Django 不会创建新的连接数据集,因为必须在 ORM 中了解所有内容才能访问结果集。它确实支持连接(我将在答案中改写它),但在 SQL 意义上不支持:Django 在遍历相关模型方面做了一些事情。
      猜你喜欢
      • 1970-01-01
      • 2013-11-12
      • 2012-03-28
      • 2020-05-26
      • 2014-05-19
      • 2022-01-21
      • 1970-01-01
      • 2017-09-18
      • 2017-11-25
      相关资源
      最近更新 更多