How to add multiply photos to one website page with django? - python

I'm writing django project for Internet Shop. On the page which describes product I have several photos for this product and I cannot add it to the template. I use 2 models with Many to many relationship - for product and for photos, and added they to template.html. But I don't see any photo in the page. My code is below:
models.py:
class ProductPhoto(models.Model):
def get_file_name(self, filename: str) -> str:
ext_file = filename.strip().split('.')[-1]
new_filename = f'{uuid.uuid4()}.{ext_file}'
return os.path.join('product_photo/', new_filename)
# product = models.ForeignKey(Product, on_delete=models.CASCADE)
photo = models.ImageField(upload_to=get_file_name)
description = models.CharField(max_length=20, blank=True)
def __str__(self):
return f'{self.description}'
class Product(models.Model):
slug = models.SlugField(max_length=200, db_index=True)
title = models.CharField(unique=True, max_length=100, db_index=True)
description_short = models.CharField(max_length=200)
description = models.CharField(max_length=500)
color = models.CharField(max_length=20)
price = models.DecimalField(max_digits=8, decimal_places=2)
sale = models.SmallIntegerField(max_length=2, blank=True)
new_arrival = models.BooleanField(default=True)
is_visible = models.BooleanField(default=True)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
photo = models.ManyToManyField(ProductPhoto)
def __str__(self):
return f'{self.title}'
class Meta:
index_together = (('id', 'slug'), )
def get_absolute_url(self):
return reverse("shop:products", args=[self.id, self.slug])
views.py:
def product_details(request, id, slug):
product = get_object_or_404(Product, id=id, slug=slug, is_visible=True)
cart = Cart(request)
return render(request,
'single-product.html',
{'product': product,
'cart': cart,
})
template.html:
<div class="product-details-left">
<div class="product-details-images">
{% for item in product.photo.all %}
<div class="lg-image">
<img src="{{ item }}" alt="">
<i class="fa fa-expand"></i>
</div>
{% endfor %}
</div>
<div class="product-details-thumbs">
{% for item in product.photo.all %}
<div class="sm-image"><img src="{{ item }}" alt="product image thumb"></div>
{% endfor %}
</div>
</div>
If I add "print(product.photo)" to "def product_details" in terminal I see:
Not Found: /shop/2/nabir-dlya-vannoyi-vislanda-3od-asort/набір для ванної 2, where "/shop/2/nabir-dlya-vannoyi-vislanda-3od-asort" is absolute_url and "набір для ванної 2" is description which added to photo.
I think it's because of path to photo in "def get_file_name", but I can mistake.
Who nows how to add photos to html template in this case?

Related

Django project to show list of categories as list then the category url displays all posts in that category

I am working on a Django project where I would like to display list of all categories on the homepage as links. When one clicks a category, they are taken to a page whereby all the posts under that field are displayed. Inside the list of posts page, I would like to show the title as the name of the category. Also I would like the url to have the name of the category.
My code is working fine in rendering those pages, but my issue is that it uses id instead of the slug field.
When I replace .id with .slug, I get the error:
ValueError at /category/electricals
Field 'id' expected a number but got 'electricals`
Here is my Models.py:
class Category(models.Model):
title = models.CharField(max_length=100)
image = models.ImageField(null=True, blank=False)
slug = models.SlugField(unique=True, null=True)
def __str__(self):
return self.title
class Service(models.Model):
category = models.ForeignKey('Category', on_delete=models.CASCADE)
title = models.CharField(max_length=100)
image = models.ImageField(null=True, blank=False)
description = models.TextField(null=False, blank=False)
service_id = models.UUIDField(default=uuid.uuid4, primary_key=True, unique=True, editable=False)
slug = models.SlugField(unique=True, null=True)
def __str__(self):
return self.title
And here is my views.py;
def landing_page(request):
categorys = Category.objects.all()
context = {'categorys':categorys}
return render(request, 'users/homepage.html', context)
def categories(request, cats):
category_services = Service.objects.filter(category=cats)
context = {'cats':cats,'category_services':category_services }
return render(request, 'users/categories.html', context)
My urls.py:
path('category/<str:cats>', views.categories, name='category'),
Template:
{% for category in categorys %}
<!-- <li><a href="{% url 'category' category.slug %}" >{{category.title}}</a></li> -->
<li><a href="{% url 'category' category.id %}" >{{category.title}}</a></li>
{% endfor %}
I have tried replacing using the code below but it does not work
category_services = Service.objects.filter(category=cats.replace('id', 'slug'))

Detail view context

how can i get all images of item into context
i tried {% for image in item.images.all %} in template but it doesn't work.
i dunno how to filter it , ty for ur answer
models
class Item(models.Model):
name = models.CharField(max_length=255)
slug = models.SlugField(max_length=255, unique=True)
brand = models.ForeignKey(Brand, on_delete=models.CASCADE, blank=True)
collection = models.ForeignKey(Collection, on_delete=models.CASCADE)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
sub_category = models.ForeignKey(SubCategory, on_delete=models.CASCADE, null=True)
description = models.TextField(blank=True)
image = models.ImageField(upload_to='photos/%Y/%m/%d/', null=True)
size = ArrayField(models.CharField(max_length=255))
price = models.PositiveIntegerField()
on_sale = models.BooleanField(default=0)
discount = models.PositiveIntegerField(null=True, blank=True)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('single_product', kwargs={'slug': self.slug})
def get_sale(self):
price = int(self.price * (100 - self.discount) / 100)
return price
class ItemImage(models.Model):
item = models.ForeignKey(Item, on_delete=models.CASCADE, null=True, related_name='images')
images = models.ImageField(upload_to='photos/%Y/%m/%d/', null=True)
def __str__(self):
return self.item.name
views
class ItemDetail(DetailView):
model = Item
context_object_name = 'item'
template_name = 'essense/single-product-details.html'
def get_context_data(self, *, object_list=None, **kwargs):
context = super().get_context_data(**kwargs)
You're pretty close. In your template tag {% for image in item.images.all %}, image refers to an instance of your ItemImage model. You need to reference the ImageField within that model, which you've named images. So, instead of
src="{{ image.url }}" use src="{{ image.images.url }}"
<div className="single_product_thumb clearfix">
<div className="product_thumbnail_slides owl-carousel">
{% for image in item.images.all %} <img
src="{{ image.images.url }}" alt="" width="360" height="539">
{% endfor %}
</div>
</div>```

Django - Add products to favorite list

I am building a supermarket store, using Django. I have to give user the possibility to add/remove items to/from the Favourite list.
So far i have done the following
models.py
class Product(models.Model):
category = models.ForeignKey('Category', null=True, blank=True,
on_delete=models.SET_NULL)
sku = models.CharField(max_length=254, null=True, blank=True)
name = models.CharField(max_length=254)
description = models.TextField()
price = models.DecimalField(max_digits=6, decimal_places=2)
rating = models.DecimalField(max_digits=6, decimal_places=1, null=True,
blank=True)
image_url = models.URLField(max_length=1024, null=True, blank=True)
image = models.ImageField(null=True, blank=True)
favourites = models.ManyToManyField(User, related_name='favourites', blank=True)
def __str__(self):
return self.name
i created favourites folder and in the folder i have:
views.py
def favourites(request, product_id):
product = get_object_or_404(Product, pk=product_id)
if product.favourites.filter(id=request.user.ide).exist():
product.favourites.remove(request.user)
else:
product.favourites.add(request.user)
return render(request, 'favourites/product_favourite_list.html')
def product_favourite_list(request):
user=request.user
favourite_products = user.favourites.all()
context = {
'favourite_products': favourite_products
}
return render(request, 'favourites/product_favourite_list.html', context)
urls.py
urlpatterns = [
path('', views.favourites, name='favourites'),
path('favourites/', views.product_favourite_list, name='product_favourite_list'),
]
in product_details i have
def product_detail(request, product_id):
""" A view to show individual product details """
product = get_object_or_404(Product, pk=product_id)
is_favourite = False
if product.favourites.filter(id=request.user.id).exists():
is_favourite = True
context = {
'product': product,
'is_favourite': is_favourite,
}
return render(request, 'products/product_detail.html', context)
product_details HTML has the following links
{% if is_favourite%}
<a href="{% url 'product_favourite_list' id=product.id %}">
<i class="fas fa-heart fa-lg"></i>
</a>
{% else %}
<a href="{% url 'product_favourite_list' id=product.id %}">
<i class="far fa-heart fa-lg"></i>
</a>
{% endif %}
i can see the favourites page. when I click on individual products. I get the error as per the attached snapshot
Hope somebody can help. thanks in advance
You provide product.id to url product_favourite_list
<a href="{% url 'product_favourite_list' id=product.id %}">
So you should do:
<a href="{% url 'product_favourite_list' %}">
You can also adjust urlpatterns, but I guess it doesn't make sense because you are showing all favourite products of user.
If you should have id in product_favourite_list add it to the path:
path('favourites/<int:id>/', views.product_favourite_list, name='product_favourite_list'),
Also add id as argument to your view:
def product_favourite_list(request, id):
...

Django: ValidationError ['ManagementForm data is missing or has been tampered with']

Django: ValidationError ['ManagementForm data is missing or has been tampered with'] i have been getting this error when i use the forminline factory module, im sorry if my question isnt placed properly, this is my first time here.
my form template is this:
{% extends 'accounts/main-form.html'%}
{% load static %}
{% block title %}
<title>CRM | Form</title>
{% endblock %}
{% block link %}
<link rel="stylesheet" type="text/css" href="{% static 'css/style1.css'%}">
{% endblock %}
{% block content %}
<div class="container">
<form action="" method="POST">
{{formset.management_form}}
{% for i in formset %}
{{i}}
{% endfor %}
<input type="submit" class="btn" value="submit">
</form>
</div>
{% endblock%}
this is the form code in views.py
def order_form(request, pk):
customers = Customer.objects.get(id=pk)
OrderFormSet = inlineformset_factory(Customer, Order, fields=('product', 'status',))
formset = OrderFormSet(request.POST)
if request.method == 'POST':
formset = OrderFormSet(request.POST, instance=customers)
if formset.is_valid():
formset.save()
return redirect('/')
context = {'formset': formset}
return render(request, 'accounts/order_form.html', context)
my models
from django.db import models
# Create your models here.
class Customer(models.Model):
name = models.CharField(max_length=200, null=True)
phone = models.CharField(max_length=200, null=True)
email = models.CharField(max_length=200, null=True)
date_created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
class Tag(models.Model):
name = models.CharField(max_length=200, null=True)
def __str__(self):
return self.name
class Product(models.Model):
CATEGORY = (
('Indoor', 'Indoor'),
('OutDoor', 'Outdoor')
)
name = models.CharField(max_length=200, null=True)
price = models.FloatField(null=True)
category = models.CharField(max_length=200, null=True, choices=CATEGORY)
description = models.CharField(max_length=200, null=True)
date_created = models.DateTimeField(auto_now_add=True)
tag = models.ManyToManyField(Tag)
def __str__(self):
return self.name
class Order(models.Model):
STATUS = (
('Pending', 'Pending'),
('Out for delivery', 'Out for delivery'),
('Delivered', 'Delivered')
)
customer = models.ForeignKey(Customer, null=True, on_delete= models.DO_NOTHING)
product = models.ForeignKey(Product, null=True, on_delete= models.DO_NOTHING)
date_created = models.DateTimeField(auto_now_add=True)
status = models.CharField(max_length=200, null=True, choices=STATUS)
def __str__(self):
return self.product.name
my form.py
from django.forms import ModelForm
from .models import Order
class Order_form(ModelForm):
class Meta:
model = Order
fields = ['product', 'status']

Show list of objects which have a reference to another model

I am trying to make a simple django app which will display a list of forums on the main page and when a user clicks on a forum title to be taken to the posts which belong to that forum
Here's the code for the post model:
class Post(models.Model):
author = models.ForeignKey('auth.User')
title = models.CharField(max_length=200)
text = models.TextField()
created_date = models.DateTimeField(
default=timezone.now)
published_date = models.DateTimeField(
blank=True, null=True)
forum = models.ForeignKey('Forum') # referinta la Forum
upload = models.FileField("Upload a file", upload_to = 'media', null=True, blank=True)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.title
And the code for the forum model:
class Forum(models.Model):
title = models.CharField(max_length=200)
published_date = models.DateTimeField(blank=True, null=True)
def __str__(self):
return self.title
The code in the views.py :
def forum_list(request):
forums= Forum.objects.filter(published_date__lte=timezone.now()).order_by('published_date')
return render(request, 'students_platform/post_list.html', {'forums': forums})
def post_list(request):
posts=Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date')
return render(request, 'students_platform/post_list.html', {'posts': posts})
Finally, i have a post_list.html file which looks like this:
<html>
<head>
<title>Informatii despre examene</title>
</head>
<body>
<div>
<h1> Informatii despre examene</h1>
<h2> Bine ati venit! </h2>
</div>
{% for forum in forums %}
<div>
<h1>{{ forum.title }}</h1>
<p>{{ forum.text|linebreaks }}</p>
</div>
{% endfor %}
</body>
</html>
How can i edit the html file so that each time i click on a forum title to take me to the posts which were added to that forum?
Add to your PostModelAdmin list_filter = ('forum',)
https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_filter
{{ forum.title }}
https://docs.djangoproject.com/en/dev/ref/contrib/admin/#reversing-admin-urls

Categories