14

I am working on invoice management system in which user can add invoice data and it will save in database and whenever user logged in the data will appear on home page but whenever user logout and try to access home page but it is giving following error.

TypeError at /

'AnonymousUser' object is not iterable

i tried AnonymousUser.is_authenticated method but still not working.

i want if user is logged in then home.html should open otherwise intro.html

here is my code views.py


from django.shortcuts import render
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.views.generic import (
    ListView,
    DetailView,
    CreateView,
    UpdateView,
    DeleteView
)
from .models import Invoicelist

def home(request):

    if request.user.is_authenticated():
        context = {
        'invoices': Invoicelist.objects.all()
        }
        return render(request, 'invoicedata/home.html', context)

    else:
        return render(request, 'invoicedata/intro.html', context)

home.html

{% extends "invoicedata/base.html" %}
{% block content %}
      {% for invoice in invoices %}
      <article class="media content-section">
        <div class="media-body">
          <div class="article-metadata">
            <small class="text-muted">{{ invoice.date_posted|date:"F d, Y" }}</small>
            <h2><a class="article-title" href="{% url 'invoice-detail' invoice.id %}">{{ invoice.issuer }}</a></h2>
          </div>

          <p class="article-content">{{ invoice.invoice_number }}</p>
          <p class="article-content">{{ invoice.date }}</p>
          <p class="article-content">{{ invoice.amount }}</p>
          <p class="article-content">{{ invoice.currency }}</p>
          <p class="article-content">{{ invoice.other }}</p>
          <div class="article-metadata">
            <small class="text-muted">{{ invoice.author }}</small>
          </div>

        </div>
      </article>
      {% endfor %}
{% endblock content %}

intro.html

{% extends "invoicedata/base.html" %}
{% block content %}
    <h2>login to your portal for great auditing services</h2>
{% endblock content %}
Akshat Zala
  • 710
  • 1
  • 8
  • 23
Mayur Satav
  • 985
  • 2
  • 12
  • 32

4 Answers4

10

Finally i got the solution that work for me

here it is

Django provides LoginRequiredMixin i used this in my invoicelistview function

from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin

class InvoiceListView(LoginRequiredMixin,ListView):
    model = Invoicelist
    template_name = 'invoicedata/home.html'
    context_object_name = 'invoices'

    def get_queryset(self):
        return self.model.objects.all().filter(author=self.request.user).order_by('-date_posted')[:2]

and that's it. Now whenever user logout then it will redirect to login page

Mayur Satav
  • 985
  • 2
  • 12
  • 32
8

I know that the question was already answered, I just want to make a summary of every method for hiding/showing information to non-authenticated users.

1. Login required decorator

If you're dealing with a functional view, you can decorate it like this:

from django.contrib.auth.decorators import login_required

@login_required
def my_view(request):
    pass

This will only show the view to authenticated users. If anonymous, they'll be redirected to the login url (settings.LOGIN_URL)

2. LoginRequiredMixin

from django.contrib.auth.mixins import LoginRequiredMixin

class MyView(LoginRequiredMixin, View):
    login_url = '/login/'
    redirect_field_name = 'redirect_to'

This is for class-based views. From Django documentation:

If a view is using this mixin, all requests by non-authenticated users will be redirected to the login page or shown an HTTP 403 Forbidden error, depending on the raise_exception parameter.

Just like the previous method, you can customize the login_url and redirect_field_name

3. Class-based view method decorator

from django.utils.decorators import method_decorator

class ProtectedView(TemplateView):
    template_name = 'secret.html'

    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
        return super().dispatch(*args, **kwargs)

4. HTML templating

Lastly, if you just want to hide some specific HTML block for non-authenticated users, you can wrap it up like this:

{% if user.is_authenticated %}
   <p> Hidden content! </p>
    <!-- You can also access the user data like this -->
   <p> {{ {{ request.user }} }} </p>
{% endif %}
martin
  • 887
  • 7
  • 23
  • Hey Martin thank you for your reply, actually i wanted give bounty for this question https://stackoverflow.com/q/61265666/8379852 but mistakenly give it to this question i know it is silly and sorry for your inconvenience but if you give any answer to mentioned question then i can given this to than you – Mayur Satav Jun 24 '20 at 09:13
  • I don't understand, the other question has nothing to to with this one and has no bounty: It's ok! – martin Jun 24 '20 at 11:54
  • @Mayur Satav could you please tick this answer ? – martin Jun 25 '20 at 22:13
4

In the HTML context, you can do:

{% if user.is_authenticated %} 
        # some arbitary stuff
        <li class="nav-item">
            <a class="nav-link" href="#"><strong>{{ user.username }}</strong></a>
        </li>
{% endif %}

and then in the python context you can do:

from django.contrib.auth.decorators import login_required

@login_required
function stuff():
.....

where @login_required should prefix any function that should only be run by a logged-in user.

Edit: and to address your specific use case, you want to do just:

if request.user.is_authenticated:.

logankilpatrick
  • 13,148
  • 7
  • 44
  • 125
  • Hey logankilpatrick thank you for your response. i tried your solution but still not working. actually i want to render home page if user is logged in otherwise intro page from same home function – Mayur Satav Apr 26 '20 at 17:14
  • 1
    In your index, you can do: `if request.user.is_authenticated:` and if it's true, render the homepage.html else the intro page. – logankilpatrick Apr 26 '20 at 17:40
  • i tried but still not working giving same error i.e. TypeError at / 'AnonymousUser' object is not iterable. – Mayur Satav Apr 26 '20 at 18:30
1

In this article, we go over how to check if a user is logged in or not in Django.

So, there's a few ways of doing this, but the way we will go over is by using the request object in Django.

By calling request.user, we are able to access the user that is currently logged in.

We then can use the is_authenticated() function to determine if a user is currently authenticated (logged into the account).

So, we'll create a simple script that if a user is logged in, we will print, "Logged in", and if a user is not logged in, we will print out, "Not logged in"

Basically, we do this all in the views.py file, which is the file where our main Python code always goes.

The code is shown below.

def index(request):
    if request.user.is_authenticated():
        print("Logged in")
    else:
        print("Not logged in")

So in this code, in our views.py file, we have a function called index, which is passed in the argument,. request.

request.user references the user that is logged in (or not if not logged in). The function, is_authenticated(), then checks to see if the user is authenticated (logged in).

If so, we print out, "Logged in". If not, we print out, "Not logged in".

Of course, there are many other things you could do besides just print out these statements.

If a user is logged in, we could render a template. If no one is logged in, we could render another template.

Other things, we could do is if a user is logged in, we could render a template. If not, we could raise a 404 Page Not Found Error.

Another thing we could do is if a user is logged in, we could render a template. If not, we could redirect the user to the login page.

So there are several things that could be done based on whether a user is logged in or not.

Umutambyi Gad
  • 4,082
  • 3
  • 18
  • 39