I have made a variation to an Item class in models.py and I think i got the template syntax right but apparently there are something wrong which i can't figure it out
Here is the model
class Item(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
price = models.FloatField()
slug = models.SlugField(unique=True)
image = models.ImageField(blank=False, upload_to='approved designs')
def __str__(self):
return self.title
class Meta:
unique_together = ('title', 'slug')
class Variation(models.Model):
item = models.ForeignKey(Item, on_delete=models.CASCADE)
title = models.CharField(max_length=120)
image = models.ImageField(null=True, blank=True)
price = models.FloatField(null=True, blank=True)
def __str__(self):
return self.title
and here is the template
{% if item.variation_set.all %}
<select class='form-control' name='size'>
{% for items in item.variation_set.all %}
<option value='{item.variation|lower}'>{{title.title|capfirst}}</option>
{% endfor %}
</select>
{% endif %}
you may want to try items.title with the 's'
Related
I have 3 models and I need to display the area and need items only if there is at least 1 product connected. If there are no products in particular Area and Need models then it should not appear in my HTML file.
I have checked the documentation and several answers related to this topic but I cannot implement it in my script.
I also tried to create my custom filter so I can apply it directly in my template but nothing worked.
My problem is that I am getting the list of all items from Need model and I don't know how to exclude empty items from HTML page.
I will appreciate any help.
models.py
class Area(models.Model):
title = models.CharField(max_length=75, blank=False)
body = models.CharField(max_length=150, default='-', blank=False)
publish = models.DateTimeField('publish', default=timezone.now)
class Need(models.Model):
title = models.CharField(max_length=75, blank=False, null=False, help_text='max 75 characters')
body = models.CharField(max_length=150, default='-', blank=False)
publish = models.DateTimeField(default=timezone.now)
need_area = models.ForeignKey(Area, on_delete=models.CASCADE, related_name='need_area')
class ProductCategory(models.Model):
title = models.CharField(max_length=400, blank=False, null=False, help_text='max 400 characters')
body = models.TextField(default='-')
publish = models.DateTimeField('publish', default=timezone.now)
category_area = models.ForeignKey(Area, on_delete=models.CASCADE, related_name='category_area', null=True)
category_need = models.ForeignKey(Need, on_delete=models.CASCADE, related_name='category_need', null=True)
class Product(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=400, blank=False)
category = models.ForeignKey(ProductCategory, on_delete = models.CASCADE, blank=True, related_name='products')
status = models.IntegerField(choices=STATUS, default=0)
def get_absolute_url(self):
return reverse("product", kwargs={'slug': self.slug})
views.py
class Search(ListView):
template_name = 'search.html'
model = Product
queryset = Product.objects.filter(status=1)
def get_context_data(self, **kwargs):
context = super(Search, self).get_context_data(**kwargs)
filter_need = Area.objects.filter(Exists(Need.objects.filter(need_area=OuterRef('pk'))))
areas = Area.objects.prefetch_related(Prefetch('need_area', queryset=filter_need, to_attr='need_area__category_need__product')).filter(need_area__category_need__product__status=1).distinct()
context['areas'] = areas
return context
search.html
{% if areas %}
{% for area in areas %}
<div class="border mb-4 pb-4 px-2">
<h2 class="fw-bold my-2">{{area.title}}</h2>
{% for need in area.need_area.all %}
<h4 class="text-muted mt-4">{{need.title}}:</h4>
{% for product_category in need.category_need.all %}
{% for product in product_category.product.all %}
<span class="rounded-pill bg-hubble text-dark f-12 p-2">{{product.title}}</span>
{% endfor %}
{% endfor %}
{% endfor %}
</div>
{% endfor %}
{% endif %}
I'm new to Django. i'm trying to display all the comments for a listing in an auction site
Help me find a way to display all the comments for a listing.
Mosdels.py
class Listing(models.Model):
title = models.CharField(max_length=64, default="")
starting_bid = models.CharField(max_length=64, default="$")
description = models.TextField(default="")
image_url = models.CharField(max_length=200, default="")
date = models.DateTimeField(default=timezone.now)
category = models.ForeignKey(Category, on_delete=models.CASCADE, default="")
def __str__(self):
return self.title
class Comment(models.Model):
comment = models.TextField(default="")
listing = models.ForeignKey(Listing, on_delete=models.CASCADE, related_name="comments", default="")
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="comments", default="")
def __str__(self):
return f"{self.user} - {self.listing}"
views.py
def listing(request, listing_id):
listing = Listing.objects.get(pk=listing_id)
comments = listing.comments.all()
return render(request, "auctions/listing.html", {
"listing":listing,
"comments":comments
})
_If you are trying to display in a template you can use something like following:
{% for listing_item in listing %}
<div>{{listing_item.title}}
{% for comment in listing_item.comment_set.all %}
<div>{{comment}}</div>
{% endfor %}
</div>
{% endfor %}
EDIT: If only sending the one listing from your view:
{{listing.title}}
{% for comment in listing.comment_set.all %}
<div>{{comment}}</div>
{% endfor %}
EDIT2: Noticed you have a related name there.
{{listing.title}}
{% for comment in listing.comments.all %}
<div>{{comment}}</div>
{% endfor %}
How do I make the page list all posts that that share the same category id? I have the category titles as a separate "foreign key" model. My goal is to be able to type in my URL so that I have the category id at the end and it shows me all the posts that have the specific category id.
"""models.py"""
class Category(models.Model):
name = models.CharField(max_length=200)
slug = models.SlugField()
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('post-category', kwargs={'pk': self.pk})
class HelpPage(models.Model):
title = models.CharField(max_length=100)
content = models.TextField(default="test")
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
product = models.CharField(max_length=100)
category = models.ForeignKey('Category', null=True, blank=True, on_delete=models.CASCADE)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk': self.pk})
"""views.py"""
class CategoryDetailView(DetailView):
model = Category
context_object_name = 'category'
template_name = 'blog/categories.html'
"""urls.py"""
from .views import (
CategoryDetailView,)
urlpatterns = [
path('category/<int:pk>', CategoryDetailView.as_view(), name='post-category'),]
"""categories.html"""
{% extends "blog/base.html" %}
{% block content %}
Category name: {{ category.name }}
{% for post in category.post_set.all %}
post: {{ post.title }}
{% endfor %}
{% endblock content %}
In your DetailView you'll need to capture the category ID passed through urls.py. Here is some info on how to do that:
https://www.agiliq.com/blog/2019/01/django-when-and-how-use-detailview/
Once you have that you can use it to run a query like this to filter for specific posts:
HelpPage.objects.filter(category__id=id)
When I try and put the {{ item.product.quantity }} in it returns an empty value. The quantity value is filled in in the database. I can't seem t pinpoint the problem. I have tried printing the quantity value but got the same results.
cart.html
{% extends 'store/main.html' %}
{% load static %}
{% block content %}
<div class="row">
<div class="col-lg-12">
<div class="box-element">
<a class="btn btn-outline-dark" href="{% url 'store' %}">← Continue Shopping</a>
<br>
<br>
<table class="table">
<tr>
<th><h5>Items: <strong>3</strong></h5></th>
<th><h5>Total:<strong> $42</strong></h5></th>
<th>
<a style="float:right; margin:5px;" class="btn btn-success" href="{% url 'checkout' %}">Checkout</a>
</th>
</tr>
</table>
</div>
<br>
<div class="box-element">
<div class="cart-row">
<div style="flex:2"></div>
<div style="flex:2"><strong>Item</strong></div>
<div style="flex:1"><strong>Price</strong></div>
<div style="flex:1"><strong>Quantity</strong></div>
<div style="flex:1"><strong>Total</strong></div>
</div>
{% for item in items %}
<div class="cart-row">
<div style="flex:2"><img class="row-image" src="{{ item.product.imageURL }}"></div>
<div style="flex:2"><p>{{ item.product.name }}</p></div>
<div style="flex:1"><p>R{{ item.product.price|floatformat:2 }}</p></div>
<div style="flex:1">
<p class="quantity">{{ item.product.quantity }}</p>
<div class="quantity">
<img class="chg-quantity" src="{% static 'images/arrow-up.png' %}">
<img class="chg-quantity" src="{% static 'images/arrow-down.png' %}">
</div>
</div>
<div style="flex:1"><p>$32</p></div>
</div>
{% endfor %}
</div>
</div>
</div>
{% endblock content %}
views.py
from django.shortcuts import render
from .models import *
def store(request):
search = request.GET.get('search')
products = Product.objects.all()
if search != '' and search is not None:
products = products.filter(name__icontains=search)
context= {'products': products}
return render(request, 'store/store.html', context)
def cart(request):
if request.user.is_authenticated:
customer = request.user.customer
order, created = Order.objects.get_or_create(customer=customer, complete=False)
items = order.orderitem_set.all()
else:
items = []
context= {'items': items}
return render(request, 'store/cart.html', context)
def checkout(request):
context= {}
return render(request, 'store/checkout.html', context)
models.py
from django.db import models
from django.contrib.auth.models import User
class Customer(models.Model):
user = models.OneToOneField(User, null=True, blank=True, on_delete=models.CASCADE)
name = models.CharField(max_length=200, null=True)
email = models.CharField(max_length=200)
def __str__(self):
return self.name
class Product(models.Model):
name = models.CharField(max_length=200, null=True)
price = models.FloatField()
digital = models.BooleanField(default=False, null=True, blank=True)
image = models.ImageField(null=True, blank=True)
def __str__(self):
return self.name
#property
def imageURL(self):
try:
url = self.image.url
except:
url = ''
return url
class Order(models.Model):
customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, null=True, blank=True)
date_ordered = models.DateTimeField(auto_now_add=True)
complete = models.BooleanField(default=False, null=True, blank=False)
transaction_id = models.CharField(max_length=100, null=True)
def __str__(self):
return str(self.id)
class OrderItem(models.Model):
product = models.ForeignKey(Product, on_delete=models.SET_NULL, null=True)
order = models.ForeignKey(Order, on_delete=models.SET_NULL, null=True)
quantity = models.IntegerField(default=0, null=True, blank=True)
date_added = models.DateTimeField(auto_now_add=True)
class ShippingAddress(models.Model):
customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, null=True)
order = models.ForeignKey(Order, on_delete=models.SET_NULL, null=True)
address = models.CharField(max_length=200, null=False)
city = models.CharField(max_length=200, null=False)
state = models.CharField(max_length=200, null=False)
zipcode = models.CharField(max_length=200, null=False)
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.address
If I do print(items) the result would be:
<QuerySet [<OrderItem: OrderItem object (4)>, <OrderItem: OrderItem object (5)>]>
So quantity is a field of the Model OrderItem.
Your query for your returned items object is:
order, created = Order.objects.get_or_create(customer=customer, complete=False)
with Order being:
class Order(models.Model):
customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, null=True, blank=True)
date_ordered = models.DateTimeField(auto_now_add=True)
complete = models.BooleanField(default=False, null=True, blank=False)
transaction_id = models.CharField(max_length=100, null=True)
def __str__(self):
return str(self.id)
and quantity in
class OrderItem(models.Model):
product = models.ForeignKey(Product, on_delete=models.SET_NULL, null=True)
order = models.ForeignKey(Order, on_delete=models.SET_NULL, null=True)
quantity = models.IntegerField(default=0, null=True, blank=True)
date_added = models.DateTimeField(auto_now_add=True)
So your returned object doesn't contain
{{ item.product.quantity }}
So you gotta use (Thanks for highlighting it #Jakumi)
{{ item.quantity }}
Hello guys I am currently working on django views and templates and met some problems.
I have a model named 'metabolites', which contains: id, name, compartment, charge and formula 5 components.
I have another model named 'Reactionsmeta', which contains: id(reactions), name, metabolie1, metabolite2, .... metabolite6. The table of this model is not filled complete, because sometimes one id corresponds to 5 metabolites, but sometimes even 20.
I write a template which can displays all the reaction, when I click on the reaction and enter the detail page, I also want to display the metabolites that involve in this reactions. My views.py and templates are written as below:
reactions_detail.html
{% extends 'Recon/Base.html' %}
{% load static %}
{% block title %}Reaction Details{% endblock %}
{% block body %}
<h1>{{ reactionsmeta.id }}</h1>
<h2>{{ reactionsmeta.name}}</h2>
<!-- Left Album Info -->
<div class="col-sm-4 col-md-3">
<div class="panel panel-default">
<div class="panel-body">
<a href="{% url 'detail_reaction' reactionsmeta.id %}">
{% if reactionsmeta.id %}
<img src="{% static "Recon/images/Logo-Technische-Universiteit-Eindhoven.jpg" %}" class="img-responsive">
{% else %}
<h3>No image to display</h3>
{% endif %}
</a>
<h1>{{ reactionsmeta.id }} <small>{{ reactionsmeta.name }}</small></h1>
</div>
</div>
</div>
views.py
from django.views import generic
from .models import Reactionsmeta,Metabolites,Reactions
from django.shortcuts import render
class IndexView(generic.ListView):
template_name = 'Recon/index.html'
context_object_name = 'Reactions_object'
def get_queryset(self):
return Reactionsmeta.objects.all()
class DetailsView(generic.DetailView):
model = Reactionsmeta
template_name = 'Recon/reactions_detail.html'
def get_context_data(self, **kwargs):
context = super(DetailsView, self).get_context_data(**kwargs)
context['metabolite'] = Metabolites.objects.all()
context['reactions'] = Reactions.objects.all()
# And so on for more models
return context
How can I write the loop in reaction_detail.html???
EDIT:
class Metabolites(models.Model):
id = models.CharField(primary_key=True, max_length=255)
name = models.CharField(max_length=255, blank=True, null=True)
compartment = models.CharField(max_length=255, blank=True, null=True)
charge = models.CharField(max_length=255, blank=True, null=True)
formula = models.CharField(max_length=255, blank=True, null=True)
notes = models.CharField(max_length=255, blank=True, null=True)
class Meta:
managed = False
db_table = 'Metabolites'
class Reactionsmeta(models.Model):
id = models.CharField(primary_key=True, max_length=255)
name = models.CharField(max_length=255, blank=True, null=True)
metabolite1 = models.ForeignKey('Metabolites', db_column='metabolite1',
blank=True, null=True, on_delete=models.CASCADE)
stoichiometry1 = models.IntegerField(blank=True, null=True)
metabolite2 = models.CharField(max_length=255, blank=True, null=True)
stoichiometry2 = models.IntegerField(blank=True, null=True)
metabolite3 = models.CharField(max_length=255, blank=True, null=True)
stoichiometry3 = models.CharField(max_length=255, blank=True, null=True)
......
stoichiometry55 = models.CharField(max_length=255, blank=True, null=True)
metabolite56 = models.CharField(max_length=255, blank=True, null=True)
stoichiometry56 = models.CharField(max_length=255, blank=True, null=True)
metabolite57 = models.CharField(max_length=255, blank=True, null=True)
stoichiometry57 = models.CharField(max_length=255, blank=True, null=True)
metabolite58 = models.CharField(max_length=255, blank=True, null=True)
stoichiometry58 = models.CharField(max_length=255, blank=True, null=True)
metabolite59 = models.CharField(max_length=255, blank=True, null=True)
stoichiometry59 = models.CharField(max_length=255, blank=True, null=True)
metabolite60 = models.CharField(max_length=255, blank=True, null=True)
stoichiometry60 = models.CharField(max_length=255, blank=True, null=True)
class Meta:
managed = False
db_table = 'ReactionsMeta'
I don't see a great way to do this since each metabolite has its own field and isn't necessarily a foreign key. It'd be easier if the metabolite were in a ManyToMany field with through defining the stoichiometry.
Django's ManyToMany Relationship with Additional Fields
https://docs.djangoproject.com/en/2.0/topics/db/examples/many_to_many/
That said, in the template you can display a Reactionsmeta metabolite1 and stoichiometry one by :
{% if reactionsmeta.metabolite1 %}
Metabolite: {% reactionsmeta.metabolite1 %}
Stoichiometry: {% reactionsmeta.stoichiometry1 %}
{% endif %}
{% if reactionsmeta.metabolite2 %}
Metabolite: {% reactionsmeta.metabolite2 %}
Stoichiometry: {% reactionsmeta.stoichiometry2 %}
{% endif %}
...
{% if reactionsmeta.metabolite60 %}
Metabolite: {% reactionsmeta.metabolite60 %}
Stoichiometry: {% reactionsmeta.stoichiometry60 %}
{% endif %}
Problems with the above:
It's terrably repetative
If the fields are in fact Foreign Keys their raw values wont't mean anything to the user.
EDIT: Response to comment that CharFields are in fact FKs.
So I think you need to query db for the information about the metabolites in the view and return that to the template. I think, by design, templates are not supposed to be able to access the db.
EDIT: I'm afraid you're going to have to learn how to write custom views. It's really not bad but it's hard to do some of the things you're attempting just using the generics.
https://docs.djangoproject.com/en/2.0/topics/http/views/