Django prefetch_related () в представлении на основе класса ListView - PullRequest
0 голосов
/ 29 марта 2020

У меня есть простой блог с двумя моделями: одна для поста и одна для комментария, например:

class Post(models.Model):
    title = models.CharField(max_length=100)
    # content = models.TextField()
    content = RichTextUploadingField(blank=True, null=True, config_name='claudiu_cfg')
    date_posted = models.DateTimeField(default=timezone.now)
    author = models.ForeignKey(User, on_delete=models.CASCADE)

def __str__(self):
    return self.title

def get_absolute_url(self):
    return reverse('post-detail', kwargs={'pk': self.pk})

class Comment(models.Model):
    author = models.CharField(max_length=20)
    text = models.TextField(max_length=350)
    date_posted = models.DateTimeField(default=timezone.now)
    post = models.ForeignKey(Post, on_delete=models.CASCADE)

def __str__(self):
    return self.author

Я хочу показать все посты (разбитые на страницы) и сколько комментариев у каждого. Мои views.py:

class PostListView(ListView):
    model = Post
    template_name = 'blog/home.html'
    context_object_name = 'posts'
    ordering = ['-date_posted']
    paginate_by = 5

Точно так же я получал все сообщения, но теперь я хочу получить доступ к таблице комментариев с минимальным выбором. Я знаю, что один из способов сделать это - определить набор запросов и сделать это следующим образом:

class PostListView(ListView):
    model = Post
    template_name = 'blog/home.html'  # <app>/<model>_<viewtype>.html
    context_object_name = 'posts'
    ordering = ['-date_posted']
    paginate_by = 5
    queryset = Post.objects.all().prefetch_related()

Однако это не позволяет получить доступ к данным комментариев.

Затем я попытался перезаписать get_queryset() функция прыжка, чтобы получить желаемый результат. Все еще безуспешно.

def get_queryset(self):
    posts = Post.objects.all().prefetch_related('pk__comment').all()
    comments = Comment.objects.all().prefetch_related('post')

    print(dir(posts))
    print('---------------------')
    print(posts._prefetch_done)

return posts.order_by('-date_posted')

Это все еще не работает, и я не могу понять, откуда go отсюда. Я прочитал документацию, но это все равно не помогло мне.

Пожалуйста, помогите, так как мне некому обратиться за помощью, когда дело доходит до django.

Похоже, решение было ближе, чем я ожидал, основываясь на ответах @dirkgroten, мне удалось исправить мою проблему следующим образом:

class PostListView(ListView):
    model = Post
    template_name = 'blog/home.html'  # <app>/<model>_<viewtype>.html
    context_object_name = 'posts'
    ordering = ['-date_posted']
    paginate_by = 5
    queryset = Post.objects.all().prefetch_related('comment_set').all()

Чтобы отобразить количество комментариев в моем шаблоне, в a для l oop я добавил:

{{ post.comment_set.all|length }}

Спасибо, без вашей помощи это заняло бы у меня еще несколько часов, если не дней.

...