Django: вытащить связанные с пользователем посты

Совсем недавно познакомился с select_related в Django. У меня наконец то получилось вытащить связанных с моделью пользователей. Позже, мне захотелось пойти от обратного (т.е вытащить связанные с пользователями посты, но уже из модели User). Я попытался пойти тем же путем. Прочитал, что для обратной совместимости, нужно указать параметр related_name в модели Post. Дописал код (созданые в процессе поля, я отметил знаком # для наглядности). Я попробовал несколько вариаций, но у меня так ничего и не заработало. Помогите разрешить данные вопросы. А конекретно:

  1. как правильно состовить запрос в views.py, что бы получить список пользователй со связанными постами, не нагружая бд.
  2. как отобразить этот запрос в html что бы получить последовательность типа {% for author in authors %} {{ author }} {{ author.post_author }} {% endfor %}

models.py

User = get_user_model() 

class Post(models.Model):
    title = models.CharField(max_length=50)
    author = models.ForeignKey(User, on_delete=models.CASCADE, null=True, related_name='post_authors')

view.py

def index(request):
    template_name = 'blog/index.html'
    posts = Post.objects.select_related('author')
    # authors = User.objects.select_related('post_authors')
    context = {'posts': posts,
               #'authors': authors
    }
    return render(request, template_name, context)

index.html

{% for post in posts %}
    {{ post.title }}
    {{ post.author }}
{% endfor %}


#{% for author in authors %}
#    {{ author }}
#    {{ author.post_authors }}
#{% endfor %}

Вроде разобрался..

models.py

User = get_user_model() 

class Post(models.Model):
    title = models.CharField(max_length=50)
    author = models.ForeignKey(User, on_delete=models.CASCADE, null=True, related_name='posts')

views.py

def index(request):
    template_name = 'index.html'
    authors = User.objects.prefetch_related('post_authors')
    context = {'authors': authors}
    return render(request, template_name, context)

index.html

{% for author in authors %}
    {{ author }}
    {% for author_posts in author.posts.all %}
        {{ author_posts }}
    {% endfor %}
{% endfor %}

Стоит обратить внимание на 3 вещи.

  1. Когда я вытаскивал автора из публикаций, я использовал select_related(), но когда я захотел вытащить уже из автора, связанные с ним публикации, мне понадоблся prefetch_related() вместо select_related() т.к у публикации может быть только один автор, а вот уже у автора, может быть много публикаций.
  2. Если не задавать related_name, то джанга создаст его автоматически и оно будет выглядеть как название модели с маленькой бувы + _set. Т.е в данном случае post_set.
  3. Если по какой то причине, вы не хотите создавать атрибут для обратной связи, вы можете провернуть это с помощью related_name='+'
Вернуться на верх