Это отличный вопрос для применения 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))
Редактирование на основе комментариев Пауло:
Вот тестовый набор моделей, который, как мне кажется, соответствует псевдокоду 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)
Затем некоторые данные, где и пользователь1, и пользователь2 пишут статьи в блоге2:
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)
)
(WitПо поводу предложения distinct()
, если вы добавите больше статей для любого автора, вы получите несколько b2
записей в результатах набора запросов.)
Как я уже сказал, это отличное упражнение ORM!