Reputation: 55
in my Django project, I have a list of items where users specify categories while submitting "Crate New Item" form. The default route shows this list of items with the title, description and category of the item. Users can click on each category to be redirected to that related category's page where I'm trying to display all items under that category.
To do that, I want to check if the category submitted in the form is already in our Category database. If yes, the item should be added under the existing category's page and if not, a new category should be created.
However, I get an attribute error while trying to check that in form submission and I'm stuck. Would appreciate any help.
AttributeError at /create
'QuerySet' object has no attribute 'name'
error line : if category == all_categories.name:
models.py:
class User(AbstractUser):
pass
class Category(models.Model):
name = models.CharField(max_length = 64, null = True)
class AuctionItem(models.Model):
user = models.ForeignKey(User, on_delete = models.CASCADE, related_name = "created_by")
title = models.CharField(max_length = 64)
description = models.TextField()
price = models.DecimalField(max_digits = 100 ,decimal_places = 2)
image = models.URLField(blank = True)
category = models.ForeignKey(Category, on_delete = models.CASCADE, related_name = "item_category")
date = models.DateTimeField(auto_now_add = True)
urls.py:
urlpatterns = [
path("", 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_listing, name="create"),
path("listing/<int:listing_id>", views.listing, name = "listing"),
path("<str:user>/watchlist", views.watchlist, name= "watchlist"),
path("closed", views.closed, name = "closed"),
path("category/<int:category_id>", views.category, name = "category")
]
views.py:
@login_required
def create_listing(request):
if request.method == "POST": #if the create listing form is submitted
title = request.POST["title"] #get the provided title
description = request.POST["description"] #get the provided description
price = request.POST["price"] #get the provided price
image = request.POST["image"] #get the provided image
category = request.POST["category"] #get the provided category
all_categories = Category.objects.filter(name = category)
if category == all_categories.name:
item = AuctionItem.objects.create( #create new auction item with given properties
user = request.user,
title = title,
description = description,
price = price,
image = image,
category = category
)
else:
new_category = Category.objects.create(name = category)
item = AuctionItem.objects.create( #create new auction item with given properties
user = request.user,
title = title,
description = description,
price = price,
image = image,
category = new_category
)
return HttpResponseRedirect(reverse("index")) #after submitting the form, redirect user to the main page
return render(request, "auctions/create_listing.html")
def category(request, category_id):
category = Category.objects.get(id=category_id)
items = AuctionItem.objects.filter(category=category)
return render(request, "auctions/category.html", {
"items" : items,
"name" : category.name
})
category.html:
{% extends "auctions/layout.html" %}
{% block body %}
<h2>Category: {{name}}</h2>
{% for item in items %}
<div class = "frame">
{% if item.image %}
<img src="{{item.image}}" style= "width: 15vw;">
{% endif %}
{% if user.is_authenticated %}
<h4><a href="{% url 'listing' item.id %}">{{item.title}}</a></h4>
{% else %}
<h4>{{item.title}}</h4>
{% endif %}
<br>
<div id="text"><strong>Starting Price:</strong> ${{item.price}}</div>
<div id="text"><strong>Description:</strong> {{item.description}}</div>
{% if item.category %}
<div id="text"><strong>Category: </strong><a href="{% url 'category' item.category.id %}">{{ item.category.name }}</a></div>
{% endif %}
<br>
<div id="created">Created by {{item.user}}, on {{item.date}}</div>
</div>
{% endfor %}
{% endblock %}
Upvotes: 0
Views: 1713
Reputation: 1012
This is the problem:
all_categories = Category.objects.filter(name = category)
filter() Returns a new QuerySet containing objects that match the given lookup parameters.
You need to use one of these because there is no such data in your table.
# import Http404
from django.http import Http404
# try except logic
try:
all_categories = Category.objects.get(name = category)
except Category.DoesNotExist:
raise Http404("Given query not found....")
or
# import get_object_or_404()
from django.shortcuts import get_object_or_404
all_categories = get_object_or_404(Category, name = category)
Upvotes: 1
Reputation: 148
In your views.py
file, You want to do a comparison name
attribute on a list.
all_categories = Category.objects.filter(name = category)
if category == all_categories.name:
the all_categories
is a list of category objects.
all_categories = [ object, object, object]
And when you want to compare it like this:
if category == all_categories.name:
The name
attribute no longer exists for the all_categories = [ object, object, object]
.
you should check your category like this:
if Category.objects.filter(name=category).exists():
... use the exist category to relate you AuctionItem ...
else:
... create new category for relate your AuctionItem ...
Upvotes: 0