Why is the user logged out after submitting a form in django?

Viewed 332

When I submit a form as a logged in user, I am suddenly logged out, as shown below. I'm not able to embed images yet because I don't have 10 reputation. Here are the linked images:

Submitting the Form

After submitting the form

views.index

from django.db import IntegrityError
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render
from django.urls import reverse

from .models import User, Bid, Auction, Comment

def index(request):
    if request.method == "POST":
        
        title = request.POST["title"]
        bid = int(request.POST["startingBid"])
        category = request.POST["category"]
        image = request.POST["img"]
        description = request.POST["description"]

        listing = Auction(name=title, bid=bid,description=description,url=image, category=category)
        listing.save()

        listings = Auction.objects.all()

        #user.is_authenticated == True here
  
        return render(request, "auctions/index.html", {
            "listings": listings,
            "user": request.user.username,
        })
    return render(request, "auctions/index.html")

urls.py


from . import views

urlpatterns = [
    path("home", views.index, name="index"),
    path("login", views.login_view, name="login"),
    path("logout", views.logout_view, name="logout"),
    path("register", views.register, name="register"),
    path("create", views.create, name="create"),
]

index.html

{% extends "auctions/layout.html" %}

{% block body %}
    <h2>Active Listings</h2>

    {% if not user.is_authenticated %}
        Please login to see active listings.
    {% endif %}
    {% if user.is_authenticated %}
        {% for listing in listings %}
            <div class="card bg-light">
                <div class="card-body">
                    <div class="row">
                        <div class="col-sm">
                            <img src="{% url 'listing.url' %}" class="img-fluid" alt="Listing image">
                        </div>
                        <div class="col-sm">
                            <div class="row">
                                <div class="col">
                                    <h2>{{ listing.name }}</h2>
                                </div>
                            </div>
                            <div class="row">
                                <div class="col">
                                    <h6>Starting Bid: ${{ listing.bid }}</h6>
                                    <p>Category: {{ listing.category }}</p>
                                </div>
                            </div>
                            <div class="row">
                                <div class="col">
                                    <p>{{ listing.description }}</p>
                                </div>
                            </div>
                            <div class="row">
                                <div class="col">
                                    <small class="text-muted">Created {{ listing.dateTime }}</small>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        {% endfor %}
    {% endif %}
{% endblock %}

models.Auction and models.User

from django.contrib.auth.models import AbstractUser
from django.db import models
from datetime import datetime
from django.core.validators import MinValueValidator

class User(AbstractUser):
    pass

class Auction(models.Model):
    name = models.CharField(max_length=64,default="")
    bid = models.PositiveIntegerField(validators=[MinValueValidator(0),])
    description = models.CharField(max_length=200, blank=True, default="")
    dateTime = models.DateTimeField(auto_now=True)
    url = models.URLField(max_length=300, default="", blank=True)
    category=models.CharField(max_length=50, default="")

    def __str__(self):
        return f"{self.name}"

When the user submits the form, request.method in views.index equals "POST" and user.is_authenticated is True until the template is rendered. I want the user to be taken back to the index page. As shown in the images, "Please log in to see active listings." is being shown, meaning user.is_authenticated somehow becomes false. Why is this happening?

2 Answers

As I can see, your views.index function should override login. Something like this

@login_required(login_url = "user:login")
def index(request):

The template context variable user is set to the username - not the User instance:

        return render(request, "auctions/index.html", {
        "listings": listings,
        "user": request.user.username,  # change to just request.user
    })

The user isn't logged out - the template simply checks the string username for a is_authenticated attribute but obviously finds none. user.is_authenticated is therefore always false.

Related