Django Querysets ленивы, поэтому они не оценивают, пока вы не попытаетесь получить доступ к результатам. Вы можете цепочки фильтров, как вы сделали, или положить их все в один. Я думаю, это действительно зависит от того, есть ли у вас вся информация при запуске или вам нужно динамически добавлять фильтры на основе чего-либо. В любом случае, конечный результат запроса будет одинаковым. Ознакомьтесь с документацией Джанго по теме
friends_posts = Post.objects.filter(privacy=False, user=friends[0])
friends_posts = Post.objects.filter(privacy=False).filter(user=friends[0])
для вашей второй части. Я думаю, что вы просто хотите простой фильтр «__in», который даст вам все сообщения, пользователь которых находится в друзьях. ( документы Джанго )
friends_posts = Post.objects.filter(privacy=False, user__in=friends)
Django по умолчанию позволит вам иметь «друзей» как сам набор запросов и выполнит подзапрос, когда он получит результаты. Если вы не хотите выполнять подзапрос, вы можете отправить своих друзей в список, и он будет запрашивать друзей, а затем запрашивать сообщения.
friends_posts = Post.objects.filter(privacy=False, user__in=list(friends))