Hey guys I get this error thrown up at me when I click a product on my Django project. I assume its a spelling mistake in either my view or models but I cant see anything. I've attach both an image of the error and my code. Any help would be appreciated. apologies if my post does not contain the correct information needed I'm new to coding.
Views
from django.shortcuts import render, get_object_or_404
from .models import Category,Product
def allProdCat(request, category_id=None):
c_page = None
products = None
if category_id != None:
c_page = get_object_or_404(Category, id=category_id)
products = Product.objects.filter(category=c_page, available=True)
else:
products = Product.objects.all().filter(available=True)
return render(request,'shop/category.html',{'category':c_page, 'products':products})
def prod_detail(request,category_id,product_id):
try:
product = Product.objects.get(category_id=category_id,id=product_id)
except Exception as e:
raise e
return render(request,'shop/product.html', {'product':product})
models
import uuid
from django.db import models
from django.urls import reverse
class Category(models.Model):
id = models.UUIDField(
primary_key=True,
default=uuid.uuid4,
editable=False)
name = models.CharField(max_length=250, unique=True)
description = models.TextField(blank=True)
class Meta:
ordering = ('name',)
verbose_name = 'category'
verbose_name_plural = 'categories'
def get_absolute_url(self):
return reverse('phoneshop:products_by_category', args=[self.id])
def __str__(self):
return self.name
class Product(models.Model):
id = models.UUIDField(
primary_key=True,
default=uuid.uuid4,
editable=False)
name = models.CharField(max_length=250, unique=True)
description = models.TextField(blank=True)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
price = models.DecimalField(max_digits=10, decimal_places=2)
image = models.ImageField(upload_to='product', blank=True)
stock = models.IntegerField()
available = models.BooleanField(default=True)
created = models.DateTimeField(auto_now_add=True, blank=True, null=True)
updated = models.DateTimeField(auto_now_add=True, blank=True, null=True)
class Meta:
ordering = ('name',)
verbose_name = 'product'
verbose_name_plural = 'products'
def get_absolute_url(self):
return reverse('phoneshop:prod_detail', args=[self.category.id, self.id])
def __str__(self):
return self.name
category.html:
{% extends "base.html" %}
{% load static %}
{% block metadescription %}
{% if category %}
{{ category.description|truncatewords:155 }}
{% else %}
Welcome to the cushion store where you can buy comfy and awesome cushions.
{% endif %}
{% endblock %}
{% block title %}
{% if category %}
{{ category.name }} - The Fantastic Electronic ShopnDrop
{% else %}
See our wide range of products including everything from phones to tablets - The Fantastic Electronic ShopnDrop
{% endif %}
{% endblock %}
{% block content %}
<!--Breadcrumb navigation-->
{% if category %}
<div class="row my_row_class">
<div class="mx-auto">
<p>Our Product Collection | {{category.name}}</p>
</div>
</div>
{% endif %}
<div class="mx-auto">
{% if category %}
<img class="my_image" src="{{category.image.url}}" alt="{{category.name}}">
</div>
<br>
<div>
<h1 class="text-center my_title">{{category.name}}</h1>
<p class="text-justify">{{category.description}}</p>
</div>
{% else %}
<img class="my_image my_image_padding" src="{% static 'images/banner.jpg' %}" alt="Our Products Collection">
</div>
<br>
<div>
<h1 class="text-center my_title">Our Products Collection</h1>
<p class="text-justify">Find a phone can be difficult at the best of times. With horrible products and prices its a nightmare
But with our wide range of products, The Fantastic Electronic ShopnDrop, could one be the one stop shop
for you.
</p>
</div>
{% endif %}
<div class="container">
<div class="row mx-auto">
{% for product in products %}
<div class="my bottom margin col-9 col-lg-4 col-sm-12 col-md-4">
<div class="cart text-center" style="min-width: 18rem;">
<img class = "card-img-top my_image"><img src="{{product.image.url}}" alt="{{product.name}}">
<div class="card-body">
<h4>{{product.name}}</h4>
<p>€{{product.price}}</p>
</div>
</div>
</div>
{% endfor %}
</div>
<br>
</div>
{% endblock %}
product.html
{% extends "base.html" %}
{% load static %}
{% block metadescription %}
{{ product.description|truncatewords:155 }}
{% endblock %}
{% block title %}
{{ product.name }} - The Fantastic Electronic ShopnDrop
{% endblock %}
{% block content %}
<div class="row my_prod_row_class">
<div class="mx-auto">
<p>Home | {{product.category}} | {{product.name}}</p>
</div>
<div class="container">
<br>
<div class="row">
<div class="col-12 col-sm-12 col-ml-12 col-lg-6 text-center">
<div style="min-width: 18rem;">
<img src="{{product.image.url}}" alt="{{product.name}}">
</div>
</div class="col-12 col-sm-12 col-md-12 col-lg-6">
<div>
<div>
<h1 class="my_prod_title"></h1>{{product.name}}</h1>
<p>€{{product.price}}</p>
<p class="my_title">Product Description</p>
<p class="text-justify my_prod_text">{{product.description}}</p>
{% if product.stock == 0%}
<p class="text-justify my_prod_text"><b>Out of Stock</b></p>
{% else %}
Add to Cart
{% endif %}
</div>
</div>
</div>
</div>
</div>
{% endblock %}
urls
from django.urls import path
from . import views
app_name ='phoneshop'
urlpatterns = [
path('', views.allProdCat, name ='allProdCat'),
path('<uuid:category_id>/', views.allProdCat, name='products_by_category'),
path('<uuid:cateogry_id>/<uuid:product_id>/', views.prod_detail, name='prod_detail'),
]
Related
How can I display only the history of Bids for each specific listing?
Right now my page shows all the Bids history no matter for what listing on the website
Models.py
class AuctionListing(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
start_bid = models.IntegerField(null=True)
image = models.CharField(max_length=1000, blank=True)
category = models.CharField(max_length=100)
seller = models.CharField(max_length=100, default="Default_Value")
def __str__(self):
return f"{self.title} listing | {self.seller}"
class Bid(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="user_bids")
listing = models.ForeignKey(AuctionListing, on_delete=models.CASCADE)
price = models.DecimalField(max_digits=10, decimal_places=2)
bid_time = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"{self.user} put a bid in for {self.price}"
Views.py
def view_bids(request, product_id):
return render(request, "auctions/view_bids.html")
view_bids.html
{% extends "auctions/layout.html" %}
{% block title %} Item Bid History {% endblock %}
{% block body %}
<div class="col-md-5">
<div class="thumbnail text-center">
<h4>Bid History</h4>
{% for user in user.user_bids.all %}
<strong>
{{user.user}} -
{{user.price}}$ -
{{user.bid_time}}
</strong>
<br>
{% endfor %}
</div>
</div>
{% endblock %}
Thanks for any help :)
Views.py - updated
def view_bids(request, product_id):
product = AuctionListing.objects.get(id=product_id)
return render(request, "auctions/view_bids.html", {
'product': product
})
Template - update
{% extends "auctions/layout.html" %}
{% block title %} Item Bid History {% endblock %}
{% block body %}
<div class="thumbnail text-center">
<h4>Bid History</h4>
<div class="row">
{% for bid in product.listing_bids.all %}
<div class="column">
<h6><strong>Bidder</strong></h6>
<p>{{bid.user}}</p>
</div>
<div class="column">
<h6><strong>Bid Amount</strong></h6>
<p>{{bid.price}}$</p>
</div>
<div class="column">
<h6><strong>Bid Time</strong></h6>
<p>{{bid.bid_time}}</p>
</div>
{% endfor %}
</div>
</div>
{% endblock %}
I'm trying to build a Wish list, I have a model for the listings, and a model for the wish list,
I have succeeded in making it work but..
I have to loop over all the listings first and match with the product id in my wish list so i can access the fields such as title and image..
is there any easier way to do this than looping over all the listings until finding the matched ones ?
views.py
def add_to_wishlist(request, product_id):
product = WishList.objects.filter(listing_id=product_id, user=request.user.username)
if product:
product.delete()
else:
product = WishList()
product.listing_id = product_id
product.user = request.user.username
product.save()
return HttpResponseRedirect(request.META['HTTP_REFERER'])
def wishlist(request):
product = WishList.objects.filter(user=request.user)
all_listings = AuctionListing.objects.all()
return render(request, "auctions/wishlist.html", {
'wishlist': product,
'all_listings': all_listings
})
models.py
class AuctionListing(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
start_bid = models.IntegerField(null=True)
image = models.CharField(max_length=1000, blank=True)
category = models.CharField(max_length=100)
seller = models.CharField(max_length=100, default="Default_Value")
class WishList(models.Model):
user = models.CharField(max_length=64)
listing_id = models.IntegerField()
wishlist.html
{% extends "auctions/layout.html" %}
{% block title %}Users Wishlist {% endblock %}
{% block body %}
<div class="col-12 mx-auto">
<h1 class="h3">My Wishlist</h1>
<div>Manage your wishlist</div>
{% if wishlist %}
{% for listing in all_listings %}
{% for product in wishlist %}
{% if listing.id == product.listing_id%}
<div class="card-mb-3">
<div class="row g-0">
<div class="col-md-4">
<img src="{{ listing.image }}" class="img-responsive" >
</div>
<div class="col-md-8">
<div class="card-body">
<h5 class="card-title">{{listing.title}}</h5>
<p class="card-text"> {{listing.description}}</p>
<p class="card-text"><small class="text-muted">{{listing.start_bid}}</small></p>
</div>
</div>
</div>
</div>
{% endif %}
{% endfor %}
{% endfor %}
{% else %}
<p class="card-text">No products have been added to your wishlist yet</p>
{% endif %}
</div>
{% endblock %}
Because you're getting all the WishList objects for the user, you don't need to just gather all AuctionListing objects and iterate over them. You can query them using the IDs on the WishLists you get back.
I'd do something like;
views.py
def wishlist(request):
wishlists = WishList.objects.filter(user=request.user)
listing_ids = wishlists.values_list('listing_id', flat=True)
listings = AuctionListing.objects.filter(pk__in=listing_ids)
return render(request, "auctions/wishlist.html", {
'wishlists': wishlists,
'listings': listings
})
wishlist.html
{% extends "auctions/layout.html" %}
{% block title %}Users Wishlist {% endblock %}
{% block body %}
<div class="col-12 mx-auto">
<h1 class="h3">My Wishlist</h1>
<div>Manage your wishlist</div>
{% if wishlists and listings %}
{% for listing in listings %}
<div class="card-mb-3">
<div class="row g-0">
<div class="col-md-4">
<img src="{{ listing.image }}" class="img-responsive" >
</div>
<div class="col-md-8">
<div class="card-body">
<h5 class="card-title">{{listing.title}}</h5>
<p class="card-text"> {{listing.description}}</p>
<p class="card-text"><small class="text-muted">{{listing.start_bid}}</small></p>
</div>
</div>
</div>
</div>
{% endfor %}
{% else %}
<p class="card-text">No products have been added to your wishlist yet</p>
{% endif %}
</div>
{% endblock %}
My Html
{% for category in categories %}
<div class="row">
<h3 style="padding-left: 15px; padding-bottom: 15px">{% filter upper %}{{ category.name }}{% endfilter %}</h3>
</div>
<div class="row">
{% with products=category.product.all|is_available:True %}
{% for product in products|slice:":4" %}
<div class="product-width col-xl-3 col-lg-3 col-md-3 col-sm-6 col-12 mb-30">
<div class="product-wrapper">
<div class="product-img">
<a href="{% url 'shop:product' category.name product.id %}">
<img alt="" src="{{product.image.all.0.image.url }}">
</a>
<div class="product-action">
<a class="action-wishlist" href="#" title="Wishlist">
<i class="ion-android-favorite-outline"></i>
</a>
<a class="action-cart" href="#" title="Add To Cart">
<i class="ion-android-add"></i>
</a>
</div>
</div>
<div class="product-content text-left">
<div class="product-title">
<h4>
{{ product.name|title }}
</h4>
</div>
<div class="product-price-wrapper">
<span>{{product.price}} TL</span>
</div>
</div>
</div>
</div>
{% endfor %}
{% endwith %}
</div>
<div class="row justify-content-end">
Daha Fazla...
</div>
{% endfor %}
My Model
Each product has a many-to-many relation with categories and products also have an is_available variable.
class ProductCategories(models.Model):
name = models.CharField(max_length = 60)
image = models.ImageField(upload_to = 'ProductCategories')
publish_date = models.DateTimeField(auto_now=False, auto_now_add=True)
is_available = models.BooleanField()
class Product(models.Model):
category = models.ManyToManyField(ProductCategories, related_name="product")
name = models.CharField(max_length = 60)
price = models.DecimalField(max_digits=65, decimal_places=2)
description = models.TextField()
publish_date = models.DateTimeField(auto_now=False, auto_now_add=True)
stock_number = models.IntegerField()
is_available = models.BooleanField()
My View
categories = ProductCategories.objects.all()
return render(request, 'shop/shopping.html', {'categories' : categories})
I am listing 4 products under each category but I would like to filter products that are available.
Should I filter products within view class and pass to template filtered product object separate Queryset or should I apply all filters within the template?
If I should filter them within the template as I tried above, is there any way to filter product objects according to their availability?
Thanks,
class ProductManager(models.Manager):
def is_available(self):
return self.get_queryset().filter(is_available=True)
class Product(models.Model):
--------
objects = ProductManager()
views.py
product = Product.objects.is_available()
return render(request, 'shop/shopping.html', {'products' : product})
templates
{% for product in products %}
{{ product.name }}
{% for item in product.category.all %}
{{ item.name }}
{% endfor %}{% endfor %}
Create a folder called "templatetags" at the same level as models.py and views.py in your application folder
Create a new file with the desired name in this folder. For example : 'app_tags.py'
Create a new file named __ init __.py in this folder
Open app_tags.py and write this code sample for create custom template filter:
from ..models import ProductCategories
from django import template
register = template.Library()
#register.filter
def is_available(value, arg):
products = value.filter(is_available = arg)
return products
And use like this in your Html:
{% load app_tags %}
...
...
...
{% with products=category.product.all|is_available:True %}
...
...
Please try this solution. I hope this helps to you.
we are currently building a cryptocurrency market (university project)
Each user has different cryptocurrencies in his "Wallet"
The wallet should show the sum (+ and - transactions) for each of the different cryptocurrencies.
For the moment we are only able to render a list which doesn't group the different currencies (those who have the same name)
We tried the sum and annotate functions. By doing so we aren't able to display the currency name. We get only the currency id
Here is our models file
class Currency(models.Model):
currency_name = models.CharField(max_length=40, unique=True)
symbol = models.ImageField(blank=True)
ticker = models.CharField(max_length=10)
created_at = models.DateTimeField(auto_now_add = True, null=True)
class Transaction(models.Model):
listing_id = models.ForeignKey(Listing, on_delete=models.CASCADE, null=True, blank=True)
created_at = models.DateTimeField(auto_now_add = True)
exchange_amount = models.IntegerField(null=True)
user_debit = models.ForeignKey(User, on_delete=models.CASCADE, related_name='user_id_debit', null=True)
user_credit = models.ForeignKey(User, on_delete=models.CASCADE, related_name='user_id_credit', null=True)
currency_id = models.ForeignKey(Currency, on_delete=models.CASCADE, null=True)
And our views.py
#profile page
#login_required
def profile(request):
wallet = Transaction.objects.filter(Q(user_credit=request.user) | Q(user_debit=request.user)).order_by('-created_at')
transactions = Transaction.objects.filter(Q(user_credit=request.user) | Q(user_debit=request.user)).order_by('-created_at')[:10]
listings = Listing.objects.filter(user=request.user).order_by('-created_at')[:10]
args = {'wallets': wallet, 'transactions': transactions, 'listings': listings}
return render(request, 'profile.html', args)
<!--This is our custom head title for the different urls. The base.html is loaded after this.-->
<head>
<title>SolvayCoin - Profile</title>
</head>
{% extends 'base.html' %}
{% block content %}
{% if user.is_authenticated %}
<!-- Main jumbotron for a primary marketing message or call to action -->
<div class="jumbotron">
<div class="container">
<h1 class="display-4">{{ user.first_name }} {{ user.last_name }}'s profile</h1>
<p>Username is <pan style="font-style: italic">{{ user.username }}</pan> and joined SolvayCoin {{ user.date_joined|timesince }} ago</p>
</div>
</div>
<div class="container extra-padding">
<hr>
<div class="row">
<div class="col-md-4">
<h2>My wallet</h2>
<ul class=list-unstyled >
{% for wallet in wallets %}
<li>{{ wallet.currency_id }}: {{ wallet.exchange_amount__sum|floatformat:"2" }}</li>
{% endfor %}
</ul>
</div>
<div class="col-md-4">
<h2>My transactions</h2>
{% if transactions %}
<ul class=list-unstyled >
{% for transactions in transactions %}
<li>
{% if user == transactions.user_credit %}
(+)
{% elif user == transactions.user_debit %}
(-)
{% endif %}
{{ transactions.currency_name_fixed }}{{ transactions.exchange_amount|floatformat:"2" }}
with {% if user == transactions.user_credit %}{{ transactions.user_debit }}{% elif user == transactions.user_debit %}{{ transactions.user_credit }}{% endif%}
</li>
{% endfor %}
</ul>
{% else %}
<p>No transactions are available.</p>
{% endif %}
</div>
<div class="col-md-4">
<h2>My listings</h2>
{% if listings %}
<ul class=list-unstyled >
{% for listings in listings %}
<li>Listing <!--{{ listings.id }}--> created {{ listings.created_at|date:'d/m/Y' }} at {{ listings.created_at|date:'H:i' }}</li>
{% endfor %}
</ul>
{% else %}
<p>No listings are available.</p>
{% endif %}
</div>
</div>
{% endif %}
<hr>
</div> <!-- /container -->
{% endblock %}
A django queryset solution seems tricky; since debit/credit resolution is also required here.
If performance and doing it in DB are not a major concern; I would do it in python as follows:
wallet_transactions = Transaction.objects.filter(Q(user_credit=request.user) | Q(user_debit=request.user)).order_by('-created_at').select_related('currency_id')
wallet = get_wallet(request.user, wallet_transactions)
def get_wallet(user, wallet_transactions):
wallet = defaultdict(int)
for txn in wallet_transactions:
if user == txn.user_credit:
wallet[txn.crrency_id.currency_name] += txn.exchange_amount
elif user == txn.user_debit:
wallet[txn.crrency_id.currency_name] -= txn.exchange_amount
else:
# Error; invalid transaction
pass
return wallet
# This will return something like this: {'SBS': 300, 'BTC': 121000}
I'd also think that there will be more business logic that gets added to get_wallet which definitely makes sense to be kept in the business layer of your application (python).
In your html; you can iterate over the wallet contents and print as follows:
<ul>
{% for currency_name, amount in wallet.items %}
<li>{{currency_name}} - {{amount}}</li>
{% endfor %}
</ul>
In your specific case; change this snippet:
<ul class=list-unstyled >
{% for currency_name, amount in wallet.items %}
<li>{{ currency_name }}: {{ amount|floatformat:"2" }}</li>
{% endfor %}
</ul>
I have a gallery (app in django 1.8), to which they are plugged in images. My problem is that create a link to the images in each category. I do not know how to do it on the side of the template and URL addresses are correct.
Models
class Gallery(models.Model):
title = models.CharField(max_length=200)
description = models.TextField()
image = ThumbnailerImageField(upload_to='paint/%Y/%m/%d')
class Meta:
verbose_name = "Gallery"
verbose_name_plural = " Galleries"
def __unicode__(self):
return self.title
class Paint(models.Model):
AVAILABLE = "Available"
NOT_AVAILABLE = "Not available"
STATUS_PAINT = (
(AVAILABLE, u"Dostępny"),
(NOT_AVAILABLE, u"Nie dostępny")
)
title = models.CharField(max_length=200)
gallery = models.ForeignKey(Gallery)
paint = ThumbnailerImageField(upload_to='paint/%Y/%m/%d')
price = models.CharField(max_length=50, blank=True, null=True)
status = models.CharField(choices=STATUS_PAINT, default=AVAILABLE, max_length=50)
class Meta:
verbose_name = "Picture"
verbose_name_plural = "Images"
def __unicode__(self):
return self.title
Views
class GalleryView(generic.ListView):
model = Paint
template_name = "www/gallery_list.html"
context_object_name = "gallery"
def get_queryset(self):
return Paint.objects.all()
class GalleryDetailsView(generic.ListView):
model = Gallery
context_object_name = "images"
template_name = "www/gallery_details.html"
urls
urlpatterns = [
url(r'^$', MainPage.as_view(), name='mainpage'),
url(r'^about/$', AboutMe.as_view(), name="about"),
url(r'^gallery/$', GalleryView.as_view(), name="gallery"),
url(r'^gallery1/$', GalleryDetailsView.as_view(), name="gallery_details"),
url(r'^contact/$', contact, name="contact"),
]
Template gallery list - main section
{% extends "base.html" %}
{% load thumbnail %}
{% block content %}
{% for i in images %}
<div class="row">
<div class="col-md-5">
<img src="{{ i.image|thumbnail_url:'avatar1' }}"/>
</div>
<div class="col-md-7">
<h3>{{ i.title }}</h3>
<p>{{ i.description }}</p>
</div>
</div>
<hr>
{% endfor %}
{% endblock %}
{% block content_bottom %}{% endblock content_bottom %}
Template gallery details with images of gallery
{% extends "base.html" %}
{% load thumbnail %}
{% block content %}
<table class="center-table">
<tbody>
{% for image in gallery %}
{% if forloop.counter0|divisibleby:3 %}<tr>{% endif %}
<td style="padding-left:50px;padding-right:50px;color:grey">
<a data-lightbox="roadtrip" href="{{ image.paint.url }}"><img src="{{ image.paint|thumbnail_url:'avatar' }}" class="img-thumbnail img-responsive" /></a><br>
<div style="padding-top:8px;padding-bottom:20px;">
<b>Tytuł:</b> {{ image.title }}<br>
<b>Status: </b>{{ image.status }}<br>
<b>Cena: </b>{{ image.price }}<br>
</div>
</td>
{% if forloop.counter|divisibleby:3 or forloop.last %}</tr>{% endif %}
{% endfor %}
</tbody>
</table>
{% endblock %}
{% block content_bottom %}{% endblock content_bottom %}