How to get different querysets in Django templates from Django views

Question:

In my blog app I want to allow unkown users to see articles, but I also want to allow logged users to see in the same page (somewhere else) their own articles; something like:

YOUR ARTICLES: list (only if user is logged)

ALL ARTICLES: list

Note that I need to show articles based on the user logged in because the url must be this:

path('<int:user_id>/', views.IndexView.as_view(), name='index'),

index.html:

{% if user.is_authenticated %}
   Your articles:
   <div class="container py-5">
        {% if article_list %}
            {% for article in article_list %}
                <div class="container">
                    <div class="row">
                        <div class="col">
                            {{article.author}}
                        </div>
                        <div class="col">
                            {{article.title}}
                        </div>
                        <div class="col">
                            {{article.pub_date}}
                        </div>
                        <a href=" {% url 'blog_app:detail' user_id = user.id %} ">
                            <div class="col">
                                Open article
                            </div>
                        </a>
                    </div>
                </div>
            {% endfor %}
        {% else %}
                <b>No articles!</b>
        {% endif %}
    </div>
{% endif %}

views.py:

class IndexView(ListView):
    model = Article
    template_name = 'blog_app/index.html'
    context_object_name = 'article_list'

    #return articles of a particular author
    def get_queryset(self):
        self.article = get_object_or_404(Article, author_id=self.kwargs['user_id'])
        return Article.objects.filter(
            author = self.article.author
        )

My question is: How can I get from IndexView two different querysets? One with all articles and one with articles filtered by author?

Bonus question:

Can I allow unkown users to reach the articles page if the url needs to specify the user id?

Asked By: Davide

||

Answers:

You need to specify:

def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    context['all_articles'] = Article.objects.all()
    return context

Then you can also use an if statement in th template, to check if the {{all_articles}} exists.

"Can I allow unkown users to reach the articles page if the url needs to specify the user id?"

Unauthenticated users do not have an ID, this will result in an error. If you want users to go to the author of the current article being viewed, wouldn’t it be {{article.author.id}}? (Not sure if this is what you want.)

Answered By: nigel239

Just use a standard context. Add this metod to you view (changing names, obviously):

def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    context['book_list'] = Book.objects.all()
    return context

Bonus answer:

Well, anyone can enter every instance of such view. The only thing would be to change manually number in the browser, i.e. anyone can access this link:

http://example.com/1/

But if someone is not authenticated, that link: <a href=" {% url 'blog_app:detail' user_id = user.id %} "> would raise error, but of course cause of {% if user.is_authenticated %} it’s not rendered anyway.

You need to set proper permissions to your view.

Answered By: NixonSparrow