I have the following two models:
class Listings(models.Model):
CATEGORY = [
("Miscellaneous", "Miscellaneous"),
("Movies and Television", "Movies and Television"),
("Sports", "Sports"),
("Arts and Crafts", "Arts and Crafts"),
("Clothing", "Clothing"),
("Books", "Books"),
]
title = models.CharField(max_length=64)
description = models.CharField(max_length=500)
bid = models.DecimalField(max_digits=1000000000000, decimal_places=2)
image = models.URLField(null=True, blank=True)
category = models.CharField(max_length=64, choices=CATEGORY, default=None)
user = models.ForeignKey(User, on_delete=models.CASCADE, default="")
class CloseListing(models.Model):
listings = models.ForeignKey(Listings, on_delete=models.CASCADE, default="")
user = models.ForeignKey(User, on_delete=models.CASCADE, default="")
I want to be able to query through all the objects of every listing that is not in the CloseListing model. How can I do this?
I tried the code in the answer, and I am still not able to query through all the objects of every listing not in the CloseListing model. I think it might have to do with how I am saving the model. The following code is the part of the view that deals with the CloseListing model.
def index(request):
listings = Listings.objects.all().exclude(id__in=CloseListing)
return render(request, "auctions/index.html",{
"listings": Listings.objects.all()
})
error message: TypeError: 'ModelBase' object is not iterable
because of listings = models.ForeignKey(Listings, on_delete=models.CASCADE, default="")
.
closeListing part of views.py
@login_required(login_url='login')
def listing(request, id):
#gets listing
listing = get_object_or_404(Listings.objects, pk=id)
sellar = listing.user
#close listing code
if sellar == request.user:
closeListingButton = True
else:
closeListingButton = False
closeListing = ''
try:
has_closed = get_list_or_404(CloseListing, Q(
user=request.user) & Q(listings=listing))
except:
has_closed = False
if has_closed:
closeListing = False
else:
closeListing = True
if request.method == "POST":
#close listing code
if request.POST.get('close'):
CloseListing.objects.create(user=request.user,
listings=listing)
closeListing = True
closeListingButton = False
add_or_remove_watchlist = True
winning_bid = Bids.objects.aggregate(Max('bid'))
winning_bid = Bids.objects.latest('bid')
winner = winning_bid.user
return render(request, "auctions/listing.html",{
"auction_listing": listing,
"comments": comment_obj,
"bids": bid_obj,
"closeListingButton": closeListingButton,
"closeListing": closeListing,
"closedMessage": "This listing is closed.",
"winner": winner
})
return render(request, "auctions/listing.html",{
"auction_listing": listing,
"closeListingButton": closeListingButton,
"closeListing": closeListing
})
CodePudding user response:
You should not query directly through model, which is CloseListing
, you can first filter all close listings from CloseListing
model then exclude all those listings which are in CloseListing
by exclude()
.
views.py
def index(request):
close_listings = CloseListing.objects.values('listings')
listings=Listings.objects.exclude(id__in=close_listings)
return render(request, "auctions/index.html",{
"listings": listings
})
I'd recommend you to add __str__
in Listing
model as:
class Listings(models.Model): CATEGORY = [ ("Miscellaneous", "Miscellaneous"), ("Movies and Television", "Movies and Television"), ("Sports", "Sports"), ("Arts and Crafts", "Arts and Crafts"), ("Clothing", "Clothing"), ("Books", "Books"), ] title = models.CharField(max_length=64) description = models.CharField(max_length=500) bid = models.DecimalField(max_digits=1000000000000, decimal_places=2) image = models.URLField(null=True, blank=True) category = models.CharField(max_length=64, choices=CATEGORY, default=None) user = models.ForeignKey(User, on_delete=models.CASCADE, default="") def __str__(self) -> str: return f'{self.title}'
By adding __str__
you would see instances title instead of objects.