Django displaying model on web page - python

I'm not sure where I'm going wrong. I'm creating a web store using Django/HTML/Foundations and I can't get the products that are in the database to display on the web page. I know they're in the database because when i go to admin page, they show up.
Here's the HTML piece:
{% for products in Product %}
<div class="column">
<h5>Title: {{products.product_name}}</h5>
<h5>Type: {{products.product_type}}</h5>
<h5>Price: {{products.sales_price}}</h5>
<img class="thumbnail" src="http://placehold.it/550x550">
</div>
{% endfor %}
Here's the Model:
class Product(models.Model):
product_name = models.CharField(max_length=255)
product_type = models.CharField(max_length=100)
sales_price = models.CharField(max_length=10)g
def __str__(self):
return self.product_name + " " + self.product_type + " " + self.sales_price
The only thing in my views.py for products page is: (might be where my problem lies)
def products(request):
return render(request,"products.html")
I'm new to django and python. Could someone please explain what's happening? Thanks

Your view needs to provide the products information to the template by using the context argument. See the documentation for render().
views.py:
def products(request):
context = {'products':Product.objects.all()}
return render(request,"products.html",context)
products.html:
{% for product in products %}
<div class="column">
<h5>Title: {{product.product_name}}</h5>
<h5>Type: {{product.product_type}}</h5>
<h5>Price: {{product.sales_price}}</h5>
<img class="thumbnail" src="http://placehold.it/550x550">
</div>
{% endfor %}

Have you tried changing your for loop from
{% for products in Product %}
to
{% for product in products %}
because you want to display a single product from the group of products each time you process through the loop.

Related

In views.py file ==> category_posts = Post.object.filter(category=cat) returns an empty query set. The 'Post' model has sample posts with categories

I am creating a blog application in django where i encountered this unusual issue. I am not being able to filter and display blog posts category wise. Please find my code below. Thanks in advance. I have spent two full days trying to figure this out and still
got nothing.
MODELS.py
This is the model which i have created for a blog post.
class Post(models.Model):
title = models.CharField(max_length=255)
author = models.ForeignKey(User, on_delete=models.CASCADE)
body = models.TextField()
post_date = models.DateField(auto_now_add=True)
category = models.CharField(max_length=255, default="uncategorized")
def __str__(self):
return self.title + ' | ' + str(self.author)
def get_absolute_url(self):
#return reverse('article-detail', args=(str(self.id)))
return reverse('homepage')
VIEWS.py
This is the view that i have created for a category wise blog posts.
def CategoryView(request,cat):
category_posts = Post.objects.filter(category=cat)
return render(request,'categories.html',{'category_posts':category_posts})
URLS.py
The urls.py file.
path('category/<str:cat>/', CategoryView, name = 'category'),
CATEGORIES.html
This will be the final display page where the category_posts is displayed as an empty queryset. The for loop is unable to run because category_posts is an empty queryset. Single word categories are also empty(to rule out a slugify issue)
{% extends 'base.html' %}
{% load static %}
{% block content %}
<ul>
{% for post in category_posts %}
<li>
<div class="category">
{{ post.category }}
</div>
<a href="{% url 'article-detail' post.pk %}">
<h3><b>{{ post.title }} </b></h3>
<p class=card-date>
<big>{{ post.author }}</big>
<small>-{{ post.post_date }}</small>
</p>
<p class="excerpt-text">{{ post.body | slice:"100" |safe}}</p>
<div class="article-thumbnail">
<img src="{% static "images/bg.png" %}" alt="article-thumbnail" >
</div>
<div class="overlay">
</a>
</li>
{% endfor %}
{% endblock %}

displaying images using for loop in html

I am pretty new to django and now I'm currently learning how to access images in database and display it using html. I want to put the images as elements in a list for further styling and making the page responsive using css but I don't want to write each and every image as a list item as there are more than 100 images in database. I've tried the below code but its not displaying images as a list. Please do suggest if any better way of doing it. I have image as a model in my models.py.
<div class='gallery'>
{% for x in photo %}
<ul>
<li><img class="images" src="{{x.image.url}}"/></li>
</ul>
{% endfor %}
</div>
This is the model for reference:
from django.db import models
class Photo(models.Model):
photo_uploader = models.CharField(max_length=50)
desc = models.CharField(max_length=300)
image = models.ImageField(upload_to="home/images")
This is the view:
def profile(request):
username = None
if request.user.is_authenticated:
photos_to_show = []
username = request.user.username
photos = Photo.objects.filter(photo_uploader=username)
return render(request, 'profile.html', {'name': username, 'photo': photos})
The <ul> tags should be placed outside the loop, otherwise you each time start a new <ul> and end that </ul> per image:
<div class='gallery'>
<ul>
{% for x in photo %}
<li><img class="images" src="{{ x.image.url }}"/></li>
{% endfor %}
</ul>
</div>

How can I lists all the products according to their foreign key?

I am working on my first eshop website using django framework and I got stuck on a problem.
I have created a general model for different kinds of products (like laptops, books etc.). Each product that is added to the website can be found by on its foreign key that links that product to a specific category.
The question is how can I display on laptops.html only the products that have the foreign key which points to the right category? Like, to display only the products from laptops category.
Thank you very much for your time!
EDIT:
in urls:
urlpatterns=[
path('', views.HomePage.as_view(), name='home'),
path('ComputerScience/', views.ComputerScience.as_view(), name='computer_science'),
path('category/<int:category_pk>/list-products/', views.CompSProd.as_view(), name='category_products_list')]
In computerscience.html I render all the cateogries.
Here in views.py I have the two controllers, first for categories and second for laptops for instance.
views.py
class ComputerScience(ListView):
model = ComputerScienceCategory
template_name = "computer_science.html"
context_object_name = "category"
class CompSProd(ListView):
model = ComputerScienceProducts
template_name = "laptops.html"
context_object_name = "products"
def get_queryset(self):
queryset = super().get_queryset()
# If you wish to still keep the view only for specific category use below line
category = get_object_or_404(ComputerScienceCategory, pk=self.kwargs.get('category_pk'))
queryset = queryset.filter(category=category)
return queryset
Here I have the template where I want to display all categories.
computer_science.html
<div class="computerScienceContent" id="slide">
{% for cat in category %}
<a href="{% url 'category_products_list' category.pk %} " id="aBar">
<div>
<h4 class="cSh">{{ cat.name }}</h4>
<img src="{{ cat.img.url }}" alt="image" class="img">
</div>
</a>
{% endfor %}
Here is laptops html, where I'd like to have the whole products displayed.
laptops.html
{% extends 'index.html' %}
{% block title %}
<title>Laptops</title>
{% endblock %}
{% block cont2 %}
{% endblock %}
My main goal is that to have a page (computerscience.html) where I have displayed a list with all available categories and when you click on one category, to redirect you to another page where you have listed all the products that belongs to that category.
This is the error that has been thrown to me:
Reverse for 'category_products_list' with arguments '('',)' not found. 1 pattern(s) tried: ['category/(?P<category_pk>[0-9]+)/list\\-products/$']
You should override get_queryset to filter your objects. Also as you are writing a view for a specific instance of category you would end up writing a lot of views, also when a new category would be added this would be very tedious you should use one view for all categories instead. Try this:
from django.shortcuts import get_object_or_404
class CompSProd(ListView):
model = ComputerScienceProducts
template_name = "laptops.html"
context_object_name = "products"
def get_queryset(self):
queryset = super().get_queryset()
category = get_object_or_404(ComputerScienceCategory, pk=self.kwargs.get('category_pk')) # Assuming category_pk will be passed in url
# If you wish to still keep the view only for specific category use below line
# category = get_object_or_404(ComputerScienceCategory, pk=<pk-of-category-here>)
queryset = queryset.filter(category=category)
return queryset
To pass the categories primary key in the url you need to do something as follows:
In your urls.py:
urlpatterns = [
...
path('category/<int:category_pk>/list-products/', views.CompSProd.as_view(), name='category_products_list'),
...
]
Now in the page where you display all categories:
{% for cat in category %}
<a href="{% url 'category_products_list' cat.pk %}" id="aBar">
<div>
<h4 class="cSh">{{ cat.name }}</h4>
<img src="{{ cat.img.url }}" alt="image" class="img">
</div>
</a>
{% endfor %}
Also you write id="aBar" but this line is in a loop meaning you would end up with multiple same ids you should use a class instead.

Django: best way to handle foreign key requests in template pages

Suppose you are making a site to simply list your products.
You want to upload an unspecified number of pictures for your each of your products. So you, following Django's many-to-one documentation, make two models:
# files stored under my_app/static/my_app/product_images/product_<id>/<img_name>
def product_img_dir_path(instance, filename):
return 'my_app/static/my_app/product_images/product_{0}/{1}'.format(instance.product.id, filename)
class Product(models.Model):
name = models.CharField ...
... # other attributes of the product, e.g. price, etc
class ProductImage(models.Model):
product = models.ForeignKey("Product", on_delete=models.CASCADE)
image = models.ImageField(upload_to=product_img_dir_path)
Now if I want all of the images for say product 1, I can retrieve them using:
ProductImages.objects.filter(product__pk=1)
My question starts here.
Suppose you want an index page which just shows the listings for all of your products and for simplicity, the first image associated with each product.
You make a template page with
{% for product in product list %}
<div class="product-listing" style="display:inline">
<!-- image for product goes here -->
<!-- brief description goes here -->
</div>
{% endfor %}
where product_list was passed in your context:
# inside /my_app/views.py
def index(request):
...
context = {"product_list": Product.objects.all()}
...
Question: what is the best way to also have access to the images for displaying the images in the template page?
Currently I thought constructing a parallel image list would suffice:
# inside /my_app/views.py
def index(request):
...
product_list = Product.objects.all()
image_list = [product.productimage_set.all()[0] for product in product_list]
context = {"product_list": product_list, "image_list": image_list}
...
and then somehow using the forloop counter to get the corresponding image for the product.
e.g.
{% for product in product list %}
<div class="product-listing" style="display:inline">
<img src="{{ image_list[<forloop counter>].image.url }}" />
<!-- brief description goes here -->
</div>
{% endfor %}
Is there a better way to do this?
As long as you can access product.productimage_set, you can try to iterate it in your template and do not pass it as a view context.
In your Django template:
{% for product in product_list %}
<div class="product-listing" style="display:inline">
{% for product_image in product.productimage_set.all %}
<img src="{{ product_image.image.url }}" />
<!-- brief description goes here -->
{% endfor %}
</div>
{% endfor %}
I think that it will be easier for you to solve this if you simplify your design by moving the images to your Product model.
If you want to save the path to an image it will be easier to use CharField, but if you want to save many paths why not using JSONField?
My suggestion look like this:
class Product(models.Model):
name = models.CharField(null=True, blank=True)
main_image = models.CharField(null=True, blank=True) # Optional
images = JSONField(null=True, blank=True)

Django queryset for list item

I am still fairly new to django and I ran into a problem which I am having a hard time figuring out even with using google or maybe I am not seeing the solution. So I have a model named movieTitles like so:
class movieTitle(models.Model):
title = models.Charfield(max_length=50)
image = models.URLField(max_length=100)
description = models.TextField()
year = models.PositiveSmallIntegerField()
director = models.Charfield(max_length=50)
Then I have my view as so:
from Movie.models import movieTitles
def movieListView(request):
movie = movieTitle.objects.all()
return render(request, 'index.html', {'movies':movie})
and my html as so:
<body>
{% for info in movies %}
{{info.title}}
{% endfor %}
</body>
What I want it to do is once user goes to the movie list and they decide to click on a certain movie, how can I take the user to another html page which will show the info.image, info.description, info.year, and info.director belonging to the movie they decided to click on. I know how to write the template and all that but what im confused on is how can I write the template using {{info.???}} and not having to create a template for every movie to link to but instead use the previous template in which the user chose a movie to create the details in the next template.
You should create a new view, which get a pk of choosen movie and retrives all informations about it.
# Add to urls.py
urlpatterns += [url(r'^detail/(?P<pk>\d+)/$', views.movie_detail, name='movie_detail')]
# Add to views.py
from django.shortcuts import get_object_or_404
def movie_detail(request, pk):
movie = get_object_or_404(movieTitle, pk=pk)
return render(request, 'movie_detail.html', {'movie': movie})
# movie_detail.html
<h1>Title: {{ movie.title }}</h1>
<img src="{{ movie.image }}">
{{ movie.description|linebreaks }}
<p>Year: {{ movie.year }}</p>
<p>Director: {{ movie.director }}</p>
Last thing you should do is to put right url in html with movie list
# Your initial html
<body>
{% for movie in movies %}
{{ movie.title }}
{% endfor %}
</body>
And that's all
add a unique field in ur model like id foreg:-
class movieTitle(models.Model):
id = models.Charfield(max_length=50)
title = models.Charfield(max_length=50)
image = models.URLField(max_length=100)
description = models.TextField()
year = models.PositiveSmallIntegerField()
director = models.Charfield(max_length=50)
and amke a url like this:
supppose app name is:
app_name = 'movie'
url(r'^movie-list/show/(?P<university_id>[0-9]+)/$', view.view_list, name='view-list'),
and pass ur url in template like this:
<body>
{% for info in movies %}
{{info.title}}
{% endfor %}
</body>

Categories

Resources