这是练习 Django 的 ORM 的好问题 :-)
根据预先知道的参数,有几种方法可以解决这个问题。
场景 1:您了解用户和特定博客
如果您有一个特定的博客并想简单地查找任一作者撰写的所有文章,您可以使用 Q 对象。我不认为这是你的情况,但我会把它放在这里以防万一:
from django.db.models import Q
Article.objects.filter(Q(creator=user1) | Q(creator=user2), blog=some_blog_instance)
场景 2:您只知道用户
如果您想要查找两个用户都发表过的所有博客,然后想要找到他们在这些博客中发表过哪些文章,您需要从 Blog 模型开始:
from django.db.models import Q
# Find all blogs where both user1 and user2 have written articles
blogs = Blog.objects.filter(article__creator=user1).\
filter(article__creator=user2).distinct()
# Now find which articles those were
for blog in blogs:
articles = blog.article_set.filter(Q=(creator=user1) | Q=(creator=user2))
根据 Paulo 的 cmets 进行编辑:
这是一个我认为与 OP 的伪代码匹配的模型测试集,它演示了上述代码的工作原理(至少在 sqlite3 和 postgres 上):
from django.db import models
from django.contrib.auth.models import User
class Blog(models.Model):
name = models.CharField(max_length=128)
class Article(models.Model):
name = models.CharField(max_length=128)
blog = models.ForeignKey(Blog)
creator = models.ForeignKey(User)
然后是user1和user2都在blog2上写文章的一些数据:
u1 = User.objects.create(username='u1')
u2 = User.objects.create(username='u2')
b1 = Blog.objects.create(name='b1')
b2 = Blog.objects.create(name='b2')
b3 = Blog.objects.create(name='b3')
b1_art1 = Article.objects.create(name='b1_art1', blog=b1, creator=u1)
b2_art1 = Article.objects.create(name='b2_art1', blog=b2, creator=u1)
b2_art2 = Article.objects.create(name='b2_art2', blog=b2, creator=u2)
查询:
[b.name for b in Blog.objects.filter(article__creator=user1).\
filter(article__creator=user2).distinct()]
产生:
[b2]
SQL 是(我的测试 django 应用程序被命名为 foo):
SELECT "foo_blog"."id", "foo_blog"."name"
FROM "foo_blog"
INNER JOIN "foo_article" ON ("foo_blog"."id" = "foo_article"."blog_id")
INNER JOIN "foo_article" T4 ON ("foo_blog"."id" = T4."blog_id")
WHERE ("foo_article"."creator_id" = 1 AND T4."creator_id" = 2 )
所以,虽然WHERE 子句确实有(A AND B)、A 和B 引用不同的内部连接("foo_article"."creator_id" 与T4."creator_id"),而不是同一个表(这是什么过滤器( A, B) 会生成,(即:WHERE ("foo_article"."creator_id" = 1 and "foo_article"."creator_id" = 2))
(如果没有distinct() 子句,如果您为任一作者添加了更多文章,您将在查询集结果中获得多个b2 条目。)
就像我说的,这是一个很棒的 ORM 练习!