Django model record is not getting updated

I am building an ecommerce website. But, my database records not getting updated.
Need help to find what exactly wrong. Thanks in advance!

def WatchList(request, Listing_id):
    listing = Listings.objects.get(pk=Listing_id)
    objWatchList = WatchLists.objects.filter(user = request.user, listing_id = Listing_id)
    
    objW = WatchLists()
    objW.listing_id = Listing_id
    objW.user = request.user
    objW.save()
class WatchLists(models.Model):
    listing_id = models.IntegerField(default=None)
    user = models.CharField(max_length=64, null = True, blank=True)

urls.py

path("ViewListing/<int:Listing_id>", views.WatchList, name="WatchList"),

What is the view supposed to do?

What it’s actually doing is creating a new WatchLists object each time it’s called.

You’re retrieving an instance of WatchLists and storing it in a variable named objWatchList, but then never using it again in your view. Why? It may be helpful if you provide more detail and context for this situation.

1 Like

Thank you for the reply.

When the user click ‘Add to Watchlist’ link on the page, a new record is added to the ‘WatchLists’ model. However, when the application tries to query the watchlists entries, it returns nothing. Records are not saved.

for esample, if the following filter is ran, nothing is returned.

WatchListing = WatchLists.objects.all()

Look for the error messages in your console where you’re running runserver. If the row’s not being saved, you should see some error message there. (I think I know what the problem may be, but I need to see the error message to confirm my hunch.)

There is no error in the console.

Then there’s something else going on. Have you posted the complete WatchList view, or is this an edited excerpt?

Here is the complete view:

from django.contrib.auth import authenticate, login, logout
from django.db import IntegrityError
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render
from django.urls import reverse
from django.contrib.auth.decorators import login_required
from .forms import *
from django.contrib.auth.models import User
from django.forms import modelform_factory
from django.db import connections
import logging
from django.utils import timezone
from datetime import datetime, timedelta, tzinfo

from .models import *


#Show the login screen to the user
def login_view(request):
    if request.method == "POST":

        # Attempt to sign user in
        username = request.POST["username"]
        password = request.POST["password"]
        user = authenticate(request, username=username, password=password)

        # Check if authentication successful
        if user is not None:
            login(request, user)
            return HttpResponseRedirect(reverse("index"))
        else:
            return render(request, "auctions/login.html", {
                "message": "Invalid username and/or password."
            })
    else:
        return render(request, "auctions/login.html")


# Log out function
def logout_view(request):
    logout(request)
    return HttpResponseRedirect(reverse("index"))
    

                        

# Register function
def register(request):
    if request.method == "POST":
        username = request.POST["username"]
        email = request.POST["email"]

        # Ensure password matches confirmation
        password = request.POST["password"]
        confirmation = request.POST["confirmation"]
        if password != confirmation:
            return render(request, "auctions/register.html", {
                "message": "Passwords must match."
            })

        # Attempt to create new user
        try:
            user = User.objects.create_user(username, email, password)
            user.save()
        except IntegrityError:
            return render(request, "auctions/register.html", {
                "message": "Username already taken."
            })
        login(request, user)
        return HttpResponseRedirect(reverse("index"))
    else:
        return render(request, "auctions/register.html")


# Dashboard view
def index(request):
    return render(request, "auctions/index.html",{

        "listings": Listings.objects.filter(status='Active')

    })

# Create Listing function
@login_required(login_url='/login')
def CreateListing (request):
    if request.method == 'POST':
        
        form1 = CreateListingForm(request.POST)
        if form1.is_valid():
            listing = Listings()
            listing.title = form1.cleaned_data["title"]
            listing.description = form1.cleaned_data["description"]
            listing.Price = form1.cleaned_data["Price"]
            listing.seller = request.user
            listing.category = form1.cleaned_data["category"]
            listing.created_at = datetime.now()
            listing.Image = form1.cleaned_data["Image"]
            listing.startingPrice = listing.Price
            listing.save()
          
            return HttpResponseRedirect(reverse("index",))
        
    else:
        form1 = CreateListingForm()
        return render(request,"auctions/createListing.html",{"form": form1})

# save listing changes
@login_required(login_url='/login')
def SaveListingChanges (request,Listing_id):
    if request.method == 'POST':
        
        form1 = CreateListingForm(request.POST)
        if form1.is_valid():
            listing = Listings.objects.get(pk=Listing_id)
            listing.title = form1.cleaned_data["title"]
            listing.description = form1.cleaned_data["description"]
            listing.Price = form1.cleaned_data["Price"]
            listing.seller = request.user
            listing.category = form1.cleaned_data["category"]
            listing.created_at = datetime.now()
            listing.Image = form1.cleaned_data["Image"]
            listing.save()
          
            return HttpResponseRedirect(reverse("index",))
        
  

# Edit listing view
@login_required(login_url='/login')
def EditListing(request,Listing_id):
    objList = Listings.objects.get(pk=Listing_id)
    form1 = CreateListingForm(initial={'title': objList.title, 'description': objList.description, 'category': objList.category, 'Price': objList.Price, 'Image': objList.Image}, instance=objList)
            
    return render(request, "auctions/EditListing.html",{
        
        "listing": objList,
        "form": form1,

    })


#Show active listings
@login_required
def activeListings(request):
    return render(request, "auctions/ActiveListings.html",{

        "listings":Listings.objects.filter(status='Active')

    })


# View Listing function
@login_required
def ViewListing (request,Listing_id):
    listing = Listings.objects.get(pk=Listing_id)
    objWatchList = WatchLists.objects.filter(listing_id=Listing_id,user=request.user)
    
  
    if not objWatchList:
        watchlist_flag = 0
    else:
        watchlist_flag = 1
   
    msg = ""

    if request.method == "POST":
        form = BidForm(request.POST)
        msg=2
        if form.is_valid():
            bid = form.cleaned_data["Bid"]
            if listing.Price >= bid:
                msg = 0
                
            else:
                listing.Price = bid
                listing.save()

                objBid = Bids()
                objBid.listing_id = listing
                objBid.user = request.user
                objBid.Bid = bid
                objBid.save()
                msg = 1
                    

    BidsForm1 = BidForm()
    CommentForm1 = CommentForm()
    comments = Comments.objects.filter(listing_id = Listing_id)

        
    return render(request,"auctions/ViewListing.html",{
        "Bidform": BidsForm1,
        "listing":listing,
        "Commentform":CommentForm1,
        "comments":comments,
        "msg":msg,
        "watchlist_flag":watchlist_flag,
            
    })

def WatchList(request, Listing_id):
    listing = Listings.objects.get(pk=Listing_id)
    objWatchList = WatchLists.objects.filter(user = request.user, listing_id = Listing_id)
    
    objW = WatchLists()
    objW.listing_id = Listing_id
    objW.user = request.user
    objW.save()
    


# View items in the WatchList tab
@login_required
def WatchListing(request):
    
    WatchListing = WatchLists.objects.all()
    #Create empty list to add items which are in 'Watchlists' of a user
    

    
    return render(request, "auctions/WatchList.html",{

        "WatchList_listing": WatchListing,
        "Total_watchlistings":len(WatchListing),
              
    })


# View 'Close' listings
@login_required
def CloseListing (request, Listing_id):
    
    listing_item = Listings.objects.get(pk=Listing_id)
    
    try:
        bidwinner = Bids.objects.get(listing_id=Listing_id,Bid=listing_item.Price)
        listing_item.winner=bidwinner.user
    except Bids.DoesNotExist:
        bidwinner=None
        listing_item.winner = None

    
    listing_item.status = 'Closed'
    listing_item.save()

   
    return render(request, "auctions/ClosedListing.html",{

        "listings":Listings.objects.filter(status='Closed'),
        

    })

# View 'Closed' listings
@login_required
def ClosedListing (request):
    listings = Listings.objects.filter(status="Closed")
    
    # Bid winner should be updated if the 'Admin' delete the last bid.
    for listing in listings:
        bidOnListing = Bids.objects.filter(listing_id=listing).last()
        if bidOnListing == None:
            objBid = False
        else:
            objBid = bidOnListing.Bid

        if objBid:
            listing.Price=objBid
            bidwinner = Bids.objects.get(listing_id=listing,Bid=objBid)
            listing.winner = bidwinner.user
            listing.save()

        else:
            listing.Price = listing.startingPrice
            listing.winner = None
            listing.save()


    return render(request, "auctions/ClosedListing.html",{

        "listings":Listings.objects.filter(status='Closed'),      

    })


# view for comments
@login_required
def AddComment(request, Listing_id):
    listing = Listings.objects.get(pk=Listing_id)
    if request.method == "POST":
        form = CommentForm(request.POST)
        if form.is_valid():
            comment = form.save(commit=False)
            comment.user = request.user
            comment.listing_id=Listing_id
            comment.created_at=datetime.now()
            comment.save()
            listing.comments.add(comment)
            listing.save()
                       
            return HttpResponseRedirect(reverse("ViewListing", args=(Listing_id,)))
        else:
            
            return HttpResponseRedirect(reverse("ViewListing", args=(Listing_id,)))
    else:
        return HttpResponseRedirect(reverse("ViewListing", args=(Listing_id,)))
            
           




# Show the listing categories available in the commerce site
@login_required
def CategoriesFn (request):
    return render(request, "auctions/Categories.html",{

        "categories":CATEGORY_CHOICES,
    })


# Show listings sorted as per Category
@login_required
def CatFn(request,category):
    ListingsPerCat= Listings.objects.filter(category=category,status="Active")
    return render(request, "auctions/CategoryView.html",{

        "listings": ListingsPerCat,
        "cat": category
    })



In your console log, are you seeing that WatchList view being called? (What invokes that URL? Is it a link on a page or some JavaScript?) What HTTP return code are you getting from that request?

It is not expected. Because when user click the ‘Add to WatchList’ link, it should just reload the same page (View Listing page). Console shows that the ‘View Listing’ page is reloaded.

Is there a way to upload a whole project (html, .py files) here ? May be, it will be much easier then to explain. I mean, .Zip files.

No, there really isn’t. Other people here have created github repos and posted the link here, but that’s about it.

If you look at your runserver console, you’ll see output that looks like this:

INFO "GET /admin/ HTTP/1.1" 200 50505
INFO "GET /static/admin/css/fonts.css HTTP/1.1" 200 423

What you should see are lines with the ViewListing/nnn as the url (where nnn is the Listing_id). The three digit number after the “HTTP/1.1” is the http return code - a 200 means everything worked. The number after that are the number of octets returned from the server. Anything else indicates an error.

If you can copy/paste some of your console log showing those URLs and the return code, that would help.

But again - is the link for ViewListing something like a menu entry directly on the page, or is it an AJAX request?

(There are at least two errors that I see in the view so far, but I can’t address them until I understand how that view is being used.)

1 Like

The ‘Add to WatchList’ is a link which when clicked add a listing into ‘WatchLists’ table.
The console output is as follows,

[10/Mar/2021 06:35:06] "GET /ViewListing/15 HTTP/1.1" 200 3798
[10/Mar/2021 06:35:07] "GET /ViewListing/15 HTTP/1.1" 200 3798
[10/Mar/2021 06:35:09] "GET /watchlisting HTTP/1.1" 200 1270
[10/Mar/2021 06:35:11] "GET /ActiveListings HTTP/1.1" 200 1815
[10/Mar/2021 06:35:13] "GET /watchlisting HTTP/1.1" 200 1270
[10/Mar/2021 06:35:14] "GET /ActiveListings HTTP/1.1" 200 1815

Ok, this doesn’t make sense at all. Only other thing I can think of at the moment is that you have two url entries for ViewListing, where the first is hiding the second - I can’t see any way that the ViewListing view you posted can return a 200 return code with the code as written.

I am really not sure where the problem lies. When the ‘Add to WatchList’ link is clicked, the record is not updated.

I can almost guarantee that that view is not being called. Please post your complete urls.py file. If you have more than one, please post all of them.

urlpatterns = [
    path("", views.index, name="index"),
    path("ActiveListings", views.activeListings, name="activelisting"),
    path("login", views.login_view, name="login"),
    path("logout", views.logout_view, name="logout"),
    path("register", views.register, name="register"),
   
    path("watchlisting", views.WatchListing, name="WatchLists"),
    path("categoriespage", views.CategoriesFn, name="Categories"),
    path("ViewListing/<int:Listing_id>", views.ViewListing, name="ViewListing"),
    path("ViewListing/<int:Listing_id>", views.SaveListingChanges, name="SaveListingChanges"),

    path("ClosedListing/<int:Listing_id>", views.CloseListing, name="CloseListing"),
    path("EditListing/<int:Listing_id>", views.EditListing, name="EditListing"),
    path("ClosedListings", views.ClosedListing, name="CloseListing"),
    path("AddComment/<int:Listing_id>", views.AddComment, name="AddComment"),
    path("ViewListing/<int:Listing_id>", views.WatchList, name="WatchList"),
     
    path("CreateListing", views.CreateListing, name="CreateListing"),
    path("category/<str:category>", views.CatFn, name="Category"),
]

Bingo - and that’s the problem.

You have three different entries for ViewListing/<int:Listing_id>. When there are duplicates, Django is going to call the first one.

1 Like

Thanks. I am not sure how Django call the first one. Because eventhough urls are same, their name or View Functions are different. But, I can try to change it now and see.

See the docs for the URL dispatcher.

Keep in mind that the request is being made by URL, not by view function or by name. The url is used to figure out which view function to call, and the name is only a convenience within the server - it’s optional. For requests coming in the URL is the only thing that matters.

Thank you very much!
You are genius!