Django: вытащить связанные с пользователем посты
Совсем недавно познакомился с select_related
в Django. У меня наконец то получилось вытащить связанных с моделью пользователей.
Позже, мне захотелось пойти от обратного (т.е вытащить связанные с пользователями посты, но уже из модели User). Я попытался пойти тем же путем. Прочитал, что для обратной совместимости, нужно указать параметр related_name
в модели Post
. Дописал код (созданые в процессе поля, я отметил знаком #
для наглядности). Я попробовал несколько вариаций, но у меня так ничего и не заработало. Помогите разрешить данные вопросы. А конекретно:
- как правильно состовить запрос в
views.py
, что бы получить список пользователй со связанными постами, не нагружая бд. - как отобразить этот запрос в
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 вещи.
- Когда я вытаскивал автора из публикаций, я использовал
select_related()
, но когда я захотел вытащить уже из автора, связанные с ним публикации, мне понадоблсяprefetch_related()
вместоselect_related()
т.к у публикации может быть только один автор, а вот уже у автора, может быть много публикаций. - Если не задавать
related_name
, то джанга создаст его автоматически и оно будет выглядеть как название модели с маленькой бувы + _set. Т.е в данном случаеpost_set
. - Если по какой то причине, вы не хотите создавать атрибут для обратной связи, вы можете провернуть это с помощью
related_name='+'