python - Django:每个外键返回一个过滤对象

标签 python django content-type django-orm django-comments

是否可以返回每个外键只返回一个对象的查询集?

例如,我想要从 django_comments 获取最新评论,但我只希望每个对象有一个评论(最新评论),即只返回对某个对象的最新评论并排除对该对象的所有过去评论.我想这类似于 django_comments.content_type 和 django_comments.object_pk 上的 sql group_by。

++添加信息++

最终目标是创建一个事件评论“线程”列表,根据线程具有最新评论显示/排序,就像您的标准讨论板,其主题按最近事件列出。

我认为最好的方法是抓取最新评论,然后按内容类型和 object_pk 对它们进行排序或分组,以便每个相关内容对象仅返回一个评论(最新)。然后我可以使用该评论来获取我需要的所有信息,所以线程这个词被宽松地使用,因为我真的只是捕获评论并跟随它的 pk's。

MODEL 是 django_threadedcomments,它扩展了 django_comments,为树、 child 和 parent 添加了一些字段。

查看:

...这将返回所有评论,包括父级的所有实例

comments = ThreadedComment.objects.all().exclude(is_public='0').order_by("-submit_date")

...这是理想的

comments = ThreadedComment.objects.all().exclude(is_public='0').order_by("submit_date").[plus sorting logic to exclude multiple instances of the same object_pk and content_type]

模板:

{% for comment in comments %}

TITLE: {{comment.content_object.title}}

STARTED BY : {{comment.content_object.user}}

MOST RECENT REPLY : {{comment.user}} on {{comment.submit_date}}

{% endfor %}

再次感谢!

最佳答案

这在 SQL 中是一件相当困难的事情;您可能无法通过 ORM 完成此操作。

您不能为此使用 GROUP BY。这用于告诉 SQL 如何对项目进行分组以进行聚合,这不是您在这里所做的。 "SELECT x, y FROM table GROUP BY x"是非法SQL,因为y的值没有意义。

让我们用一个清晰​​的模式来看这个:

CREATE TABLE objects ( id INTEGER PRIMARY KEY, name VARCHAR );
CREATE TABLE comments ( object_id INTEGER REFERENCES objects (id), text VARCHAR NOT NULL, date TIMESTAMP NOT NULL );

INSERT INTO objects (id, name) VALUES (1, 'object 1'), (2, 'object 2');
INSERT INTO comments (object_id, text, date) VALUES
   (1, 'object 1 comment 1', '2010-01-02'),
   (1, 'object 1 comment 2', '2010-01-05'),
   (2, 'object 2 comment 1', '2010-01-08'),
   (2, 'object 2 comment 2', '2010-01-09');

SELECT * FROM objects o JOIN comments c ON (o.id = c.object_id);

我见过的最优雅的方法是 Postgresql 8.4 的窗口函数。

SELECT * FROM (
    SELECT
        o.*, c.*,
        rank() OVER (PARTITION BY object_id ORDER BY date DESC) AS r
    FROM objects o JOIN comments c ON (o.id = c.object_id)
) AS s
WHERE r = 1;

这将按日期为每个对象选择第一个评论,最新的在前。如果您没有看到它在做什么,请自行执行内部 SELECT 并观察它如何生成 rank(),这使得它非常简单。

我知道使用 Postgresql 执行此操作的其他方法,但我不知道如何在其他数据库中执行此操作。

尝试动态地计算它可能会给您带来严重的麻烦——而且要使这些复杂的查询表现良好也需要更多的工作。您最好以简单的方式执行此操作:为每个对象存储一个 last_comment_id 字段,并在添加或删除评论时更新它,这样您就可以加入和排序。您或许可以使用 SQL 触发器来自动处理此更新。

关于python - Django:每个外键返回一个过滤对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3080326/

相关文章:

python - 我编写了这段代码,用于将列表中的值插入 mysql 数据库,但出现编程错误

python - 有没有办法从多个字典中访问具有相同名称的键?

python - 函数完成时对象是否从内存中删除? Python

python - 验证序列化器 Django Rest 框架中的外键字段

python - 如何从 django 模板中的相关模型获取单个对象

html - 为什么这个 SVG 可以在浏览器中以原始方式查看,但不能在网页中查看?

python - python中嵌套字典的setDefault

如果 TOTAL_FORMS 的数量与实际的表单数量不同,则 Django 表单集

drupal-7 - 自定义内容类型日期过后,Drupal 7 可以自动取消发布内容吗?

php - 如何使用 HTTPURLConnection 将表单数据和多个文件从我的 android 应用程序上传到我使用 PHP 的服务器?