i got a problem with getting ManyToMany field values in template, here is the code:
models.py
class Client(models.Model):
name = models.CharField(max_length=18,help_text='Nazwa firmy klienta, musi być unikalna', verbose_name='Klienci')
slug = models.SlugField(max_length=255,help_text="Wartość sugerowana automatycznie na podstawie nazwy", unique=True, verbose_name='Odnośnik')
iconwhite = models.ImageField(upload_to='iconswhite', verbose_name='ikona na białym tle', blank=True)
class Meta:
ordering = ['name']
verbose_name = "Klient"
def __str__(self):
return self.name
def __unicode__(self):
return self.name
def get_absolute_url(self):
return '/clients/%s/' % self.slug
models.py
class Projects(models.Model):
def get_picture_path(instance, filename):
return os.path.join('picture', str(instance.id), filename)
client = models.ManyToManyField(Client, verbose_name='Klient')
title = models.CharField(max_length=255, verbose_name='Tytuł projektu')
slug = models.SlugField(max_length=255, unique=True, verbose_name='Odnośnik')
status = models.CharField(max_length=1, choices=STATUS_CHOICES, default='d')
picture = models.ImageField(upload_to=get_picture_path, blank=True, null=True, help_text='Miniatura widoczna na str głównej oraz w galerii projektow')
class Meta:
verbose_name = "Projekt"
def __str__(self):
return self.title
def __unicode__(self):
return self.title
def get_absolute_url(self):
return '/projects/' + self.slug + '/'
index.html
<div class="grid_4">
<div class="container_img">
<div><img src="site_media/media/{{i.picture}}" /></div>
<div class="client_icon">
{% for client in projects.client.all %}
<img src="site_media/media/{{client.iconwhite}}" />
{% endfor %}
</div>
</div>
<div class="project_description">
<p class="projects_title">{{ i.title }}</p>
<p class="projects_description">{{ i.description|safe|removetags:"p br div"|truncatewords:9 }} <span>see more »</span></p>
</div>
</div>
I checked other similar topics, dunno what am i missing here :(
If i is the variable holding an individual project (judging by the context in your HTML), you'd need:
{% for client in i.client.all %}
{{ client }}
{% endfor %}
Related
When I am filtering the product but when I run the project I don't get the images
If I change the code Product.objects.filter(slug=slug)
To
replce the code with Product.objects.get(slug=slug)
the I am facing this type off error in my trminal
Django 'Product' object is not iterable
Views.py
def product_detail(request, slug):
try:
product = Product.objects.filter(slug=slug)
context = {
'product': product,
}
return render(request, 'buyer/product_details.html', context)
except Product.DoesNotExist:
return render(request, 'buyer/product_details.html', {'error': 'No data found.'})
URLs.py
path('product/<slug:slug>', views.product_detail, name="product_detail"),
Models.py
class Product(models.Model):
total_quantity = models.IntegerField()
availability = models.IntegerField()
feature_image = models.ImageField(upload_to='media/Product_image')
product_name = models.CharField(max_length=100)
price = models.IntegerField()
discount = models.IntegerField()
product_information = RichTextField()
model_name = models.CharField(max_length=100)
categories = models.ForeignKey(MainCategory, on_delete=models.CASCADE)
tags = models.CharField(max_length=100)
description = RichTextField()
section = models.ForeignKey(Section, on_delete=models.DO_NOTHING)
slug = models.SlugField(default='', max_length=500, null=True, blank=True)
def __str__(self):
return self.product_name
def get_absolute_url(self):
from django.urls import reverse
return reverse("product_detail", kwargs={'slug': self.slug})
class Meta:
db_table = "buyer_Product"
def create_slug(instance, new_slug=None):
slug = slugify(instance.product_name)
if new_slug is not None:
slug = new_slug
qs = Product.objects.filter(slug=slug).order_by('-id')
exists = qs.exists()
if exists:
new_slug = "%s-%s" % (slug, qs.first().id)
return create_slug(instance, new_slug=new_slug)
return slug
def pre_save_post_receiver(sender, instance, *args, **kwargs):
if not instance.slug:
instance.slug = create_slug(instance)
pre_save.connect(pre_save_post_receiver, Product)
class ProductImage(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
image_url = models.ImageField(upload_to='media/Product_image')
def __str__(self):
return self.product.product_name
HTML Page
<div class="product-image-slider">
{% for i in product.productimage_set.all %}
<figure class="border-radius-10">
<img src="{{ i.image_url }}" alt="product image"/>
</figure>
{% endfor %}
</div>
<!-- THUMBNAILS -->
<div class="slider-nav-thumbnails">
{% for i in product.productimage_set.all %}
<div><img src="{{ i.image_url }}" alt="product image"/></div>
{% endfor %}
</div>
</div>
<!-- End Gallery -->
You need to pass .url
{% for i in product.productimage_set.all %}
<figure class="border-radius-10">
<img src="{{ i.image.url }}" alt="product image"/>
</figure>
{% endfor %}
that's because:
Product.objects.get(slug=slug) returns a single object type porduct. and one single object is not iterable
and
Product.objects.filter(slug=slug) returns a Queryset[] of products (list of products)
so if you are looking to treat multiple products use the second way, but if you are looking to treat one single product, use the first one
I want to put a filter on a page which shows videos selecting an album shows up on album page not all the videos but my current filter is showing all the published videos. I couldn't find a way to put a filter based on slug that if an album's slug is matching with the current url then shows the video selecting that album. For example:- Videos created by Gaurav should only visible on Gaurav’s album not anyone else. I am all confused help me.
models.py
from django.db import models
from django.urls import reverse
STATUS = (
(1, "Publish"),
(0, "Draft")
)
class WatchCategory(models.Model):
title = models.CharField(max_length=20)
slug = models.SlugField(max_length=2000, unique=True)
def __str__(self):
return self.title
class Genre(models.Model):
title = models.CharField(max_length=20)
slug = models.SlugField(max_length=2000, unique=True)
def __str__(self):
return self.title
class Album(models.Model):
title = models.CharField(max_length=2000)
slug = models.SlugField(max_length=2000, unique=True)
image = models.CharField(max_length=2000, blank=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('Watch:album', kwargs={
'slug': self.slug
})
class Video(models.Model):
title = models.CharField(max_length=2000)
slug = models.SlugField(max_length=2000, unique=True)
thumbnail = models.CharField(max_length=2000, unique=True)
updated_on = models.DateTimeField(auto_now=True)
file = models.CharField(max_length=2000)
time = models.CharField(max_length=2000, blank=True)
about = models.TextField(blank=True)
category = models.ManyToManyField(WatchCategory)
album = models.ManyToManyField(Album)
genre = models.ManyToManyField(Genre)
created_on = models.DateTimeField(auto_now_add=True)
status = models.IntegerField(choices=STATUS, default=1)
class Meta:
ordering = ['-created_on']
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('Watch:video', kwargs={
'slug': self.slug
})
views.py
class Album(ListView):
queryset = Video.objects.filter(status=1).order_by('-created_on')
template_name = 'Watch/album.html'
paginate_by = 6
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['title'] = 'Explore & Watch your favourite'
return context
album.html
{% extends "Watch/layout.html" %}
{% load static %}
{% block content %}
<div class="video-block section-padding">
<div class="row">
{% for video in video_list %}
<div class="col-xl-3 col-sm-6 mb-3">
<div class="video-card">
<div class="video-card-image">
<a class="play-icon" href="{% url 'Watch:video' video.slug %}"><i class="fas fa-duotone fa-circle-play"></i></a>
<img class="img-fluid" src="{{ video.thumbnail }}" alt="">
<div class="time">{{ video.time }}</div>
</div>
<div class="video-card-body">
<div class="video-title">
{{ video.title }}
</div>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
{% endblock %}
I m trying to make a comment system on a blog website with using the slug instead of pk
im running into not NULL constraint failed: home_comment.post_id error
my error is coming in the form_valid function in the class based view
form.instance.post_id = self.kwargs['pk']
how do i do this ^ with the slug
form.instance.post__slug = self.kwargs['slug'] (this is showing an error)
views.py
class AddCommentView(CreateView):
model = Comment
form_class = AddCommentForm
template_name = "add_comment.html"
def form_valid(self, form):
form.instance.post__slug = self.kwargs["slug"]
form.instance.name = self.request.user
return super().form_valid(form)
models.py
class Post(models.Model):
title = models.CharField(max_length=1000, default="Title")
author = models.ForeignKey(User, on_delete=models.CASCADE)
category = models.CharField(max_length=1000, default="Category")
body = models.TextField(default="This is the Body of the Post.")
slug = models.SlugField(max_length=1000, null=True, blank=True)
created_time = models.DateTimeField(auto_now_add=True)
created_date = models.DateField(auto_now_add=True)
updated_time = models.DateTimeField(auto_now=True)
updated_date = models.DateField(auto_now=True)
likes = models.ManyToManyField(User, related_name="blog_posts_likes")
dislikes = models.ManyToManyField(User, related_name="blog_posts_dislikes")
class Meta:
verbose_name_plural = "Blogs & Posts"
def __str__(self):
return self.title
def save(self, *args, **kwargs):
self.slug = generate_slug(self.title)
super(Post, self).save(*args, **kwargs)
def get_absolute_url(self):
return f"/blogs/post/{self.slug}"
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name="comments")
name = models.ForeignKey(User, on_delete=models.CASCADE)
body = models.TextField()
date_added = models.DateField(auto_now_add=True)
time_added = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name_plural = "Post Comments"
def __str__(self):
return "%s - %s" % (self.post.title, self.name.username)
def get_absolute_url(self):
return f"/blogs/post/{self.post.slug}"
html file
{% extends "base.html" %}
{% block content %}
{% if user.is_authenticated %}
<section class="text-gray-600 body-font relative">
<div class="container px-5 py-24 mx-auto">
<div class="flex flex-col text-center w-full mb-12">
<h1 class="sm:text-3xl text-2xl font-medium title-font mb-4 text-gray-900">Add A Comment</h1>
</div>
<div class="mx-auto">
<form method="post">
{% csrf_token %}
{{form}}
<div class="p-2 w-full">
<button
class="flex mx-auto text-white bg-indigo-500 border-0 py-2 px-8 focus:outline-none hover:bg-indigo-600 rounded text-lg">Add</button>
</div>
<div class="p-2 w-full pt-8 mt-8 border-t border-gray-200 text-center">
</div>
</form>
</div>
</div>
</section>
{% endif %}
{% endblock %}
try this
def form_valid(self, form):
form.instance.post = Post.objects.get(slug=self.kwargs["slug"])
form.instance.name = self.request.user
return super().form_valid(form)
Good evening, I have a problem while learning Django. The point is that I am doing a training news site, and there is such an item as "public" - whether the news is published or not. And to display only published news, use "def get_queryset" But I need to display news only with public = True and by the date the news was created
views.py
class news(ListView):
model = Post
template_name = 'flatpages/new.html'
context_object_name = 'news'
# paginate_by = 6
ordering = '-data'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['cate'] = Category.objects.all()
return context
def get_queryset(self):
return Post.objects.filter(public=True)
models.py
class Category(models.Model):
category_name = models.CharField(max_length=64, unique=True)
subscribers = models.ManyToManyField(User, blank=True, null=True)
class Meta:
verbose_name = 'Категория'
verbose_name_plural = 'Категории'
def __str__(self):
return self.category_name
class Post(models.Model):
PostAuthor = models.ForeignKey(Author, on_delete=models.CASCADE, verbose_name='Автор поста')
PostNews = 'PN'
PostArticle = 'PA'
# «статья» или «новость»
POSITIONS = [
(PostArticle, 'Статья'),
(PostNews, 'Новость'),
]
postCategory = models.ManyToManyField(Category, verbose_name='Категория поста', through='PostCategory')
title = models.CharField(max_length=50, verbose_name='Название')
positions = models.CharField(max_length=2, choices=POSITIONS, default=PostArticle, verbose_name='Тип поста')
category_id = models.ForeignKey(Category, verbose_name='Категория', null=True, on_delete=models.CASCADE, related_name='category_id')
data = models.DateTimeField(auto_now_add=True, verbose_name='Дата создания')
data_update = models.DateTimeField(auto_now=True, verbose_name='Дата редактирования')
photo = models.ImageField(upload_to='photos/%Y/%m/%d/', verbose_name='Фото', blank=True, default='/photos/def/1.jpg/')
previewName = models.CharField(max_length=128, verbose_name='Превью поста')
text = models.TextField(verbose_name='Текст поста')
rating = models.SmallIntegerField(default=0, verbose_name='Рейтинг')
public = models.BooleanField(default=True, verbose_name='Опубликовано')
def like(self):
self.rating +=1
self.save()
def dislike(self):
self.rating -=1
self.save()
def preview(self):
return self.text[0:124] + '...'
def __str__(self):
return self.title
class Meta:
verbose_name = 'Пост'
verbose_name_plural = 'Посты'
def get_absolute_url(self):
return f'/news/{self.pk}'
html page
<div class="col-md-8">
{%for el in news%}
<div class="card mb-3">
<div class="card-header">
Категории: {{el.category_id}}
</div>
<br>
<div class="row g-0">
<div class="col-md-4">
{%if el.photo%}
<img src="{{el.photo.url}}" alt="" width="275" class="mr-3">
{%endif%}
</div>
<div class="col-md-8">
<div class="card-body">
<h5 class="card-title"><a style="color: #000000;" href="{% url 'news_detail' el.id %}">{{ el.title|censor_filter }}</a></h5>
<p class="card-text">{{ el.text|censor_filter|truncatewords:150 }}</p> Читать полную новость
</div>
</div>
<br>
<div
class="card-footer text-muted " style="text-align: right;">Рейтинг статьи: {{el.rating}}<br>
Дата публикации {{ el.data|date:'d M Y H:m' }}
</div>
</div>
</div>
{%endfor%}
</div>
https://i.stack.imgur.com/BG56m.png
If you override the get_queryset, Django will no longer order the queryset, since that is implemented in the basic implementation of the view. You should order in the .get_queryset method with:
class news(ListView):
model = Post
template_name = 'flatpages/new.html'
context_object_name = 'news'
# paginate_by = 6
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['cate'] = Category.objects.all()
return context
def get_queryset(self):
# use order_by(…) ↓
return Post.objects.filter(public=True).order_by('-data')
Note: In Django, class-based views (CBV) often have a …View suffix, to avoid a clash with the model names.
Therefore you might consider renaming the view class to NewsView, instead of news.
How can i render my variables from models in a html file, they was rendering a time ago before I made html link slug with class(DetailView) in my views.py
HTML FILE (product.html)
<h2 class="heading">{{ product.name }}</h2>
<div style="clear: both;"><br></div>
<div class="block">
<div class="img_preview">
<img src="{{ product.img }}">
<div class="categ">
{% for category in product.category.all %}
<span>{{ category }}</span>
{% endfor %}
{# <div style="clear: both"><br></div> #}
</div>
</div>
<div id="links">
{% for link in links %}
<div class="download_link">
<span>DOWNLOAD MIRROR NUMBER {{ links.number }}</span>
</div>
{% endfor %}
</div>
<div style="clear: both"></div>
<div id="games">
<div id="video_trailer">
<iframe width="560" height="317" src="{{ product.video_trailer }}" frameborder="0" gesture="media" allow="encrypted-media" allowfullscreen></iframe>
<div id="description">
<span class="title">Description</span>
<p>{{ product.description }}</p>
</div>
</div>
<div style="clear: both"><br></div>
<div id="system_requirements">
<span class="title">System Requirements</span><br>
<p>Processor: {{ product.processor }}<br>
<br>
Graphic Card: {{ product.video }}<br>
<br>
Memory: {{ product.ram }}<br>
<br>
Disk Space: {{ product.disk_space }}<br>
<br>
OS: {{ product.oS }}
</p>
</div>
</div>
<div id="screenshots">
{% for image in product_images %}
<div class="screenshot">
<img width="1920px" height="1080px" src="{{ image.image }}" >
</div>
{% endfor %}
</div>
</div>
</div>
<aside>
<div id="news">
<h2 class="heading">News</h2>
<div style="clear: both"><br></div>
{% for articles in news_articles %}
<div id="articles">
<div class="article">
<a href="{{ articles.article.get_absolute_url }}">
<img src="{{ articles.image }}">
<div style="clear: both"></div>
<span></span><div style="clear: both"></div>
</a>
<em>{{ articles.article.created }}</em>
views.py
from django.shortcuts import render
from products.models import *
from news.models import *
from django.shortcuts import get_object_or_404
from django.views.generic.detail import DetailView
class GameLink(DetailView):
# model = Product
# context_object_name = 'product'
def get_object(self):
return get_object_or_404(Product, slug__iexact=self.kwargs['slug'])
class ArticleLink(DetailView):
model = Article
context_object_name = 'article'
def get_object(self):
return get_object_or_404(Article, slug__iexact=self.kwargs['slug'])
def product(request, product_id):
product = Product.objects.get(id=product_id)
product_images = ProductImage.objects.filter(is_active=True, is_main=False, id=product_id)
links = ProductDownload.objects.filter(is_active=True, product=product_id)
news_articles = NewsImage.objects.filter(is_active=True, is_main=True)
return render(request, 'products/product.html', locals())
urls.py
from django.contrib import admin
from django.conf.urls import *
from products import views
from products.views import *
urlpatterns = [
# url(r'^games/(?P<product_id>\w+)/$', views.product, name='product'),
url(r'^games/(?P<slug>[-\w]+)/$', GameLink.as_view(template_name = 'products/product.html'), name='product'),
url(r'^articles/(?P<slug>[-\w]+)/$', ArticleLink.as_view(template_name = 'news/article.html'), name='article')
]
models.py
`
from django.db import models
from django.urls import reverse
class ProductCategory(models.Model):
name = models.CharField(max_length=128, blank=True, null=True, default=None)
is_active = models.BooleanField(default=True)
def __str__(self):
return '%s' % self.name
class Meta:
verbose_name = 'Category'
verbose_name_plural = 'Categories'
class Product(models.Model):
name = models.CharField(max_length=128, blank=True, null=True, default=None)
description = models.TextField(default=None)
processor = models.CharField(max_length=300, blank=True, null=True, default=None)
video = models.CharField(max_length=300, blank=True, null=True, default=None)
ram = models.CharField(max_length=300, blank=True, null=True, default=None)
disk_space = models.CharField(max_length=300, blank=True, null=True, default=None)
oS = models.CharField(max_length=300, blank=True, null=True, default=None)
video_trailer = models.CharField(max_length=10000, blank=True, null=True, default=None)
img = models.CharField(max_length=10000, blank=True, null=True, default=None)
category = models.ManyToManyField(ProductCategory, blank=True, default=None)
is_active = models.BooleanField(default=True)
created = models.DateTimeField(auto_now_add=True)
slug = models.SlugField(primary_key=True, max_length=250, unique=True, default=None)
def __str__(self):
return '%s' % self.name
def get_absolute_url(self):
return reverse('product', args=[str(self.slug)])
class Meta:
verbose_name = 'Game'
verbose_name_plural = 'Games'
class ProductDownload(models.Model):
product = models.ForeignKey(Product, blank=True, null=True, default=None, on_delete=False)
link = models.CharField(max_length=10000, blank=True, null=True, default=None)
is_active = models.BooleanField(default=True)
number = models.PositiveIntegerField(blank=True, default=True)
def __str__(self):
return '%s' % self.product.name
class Meta:
ordering = ['number']
class Meta:
verbose_name = 'Download Link'
verbose_name_plural = 'Download Links'
class ProductImage(models.Model):
product = models.ForeignKey(Product, blank=True, null=True, default=None, on_delete=False)
image = models.CharField(max_length=10000, blank=True, null=True, default=None)
is_main = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
def __str__(self):
return '%s' % self.product
class Meta:
verbose_name = 'Image'
verbose_name_plural = 'Images'
HTML file show only Product variables that are called with {{ product.___ }} but doesn't renders the rest like my links called with :
{% for link in links %}
{{ link.link }}
{% endfor %}
or like my articles...
How should I proceed to render on my page needed models.
Image of file paths
here
There are different forms to add adicional 'variables' using a DetailView (link)
For example:
class GameLink(DetailView):
def get_object(self):
return get_object_or_404(Product, slug__iexact=self.kwargs['slug'])
def links(self):
return ProductDownload.objects.filter(is_active=True, product=self.object)
And in product.html:
{% for link in view.links %}
<div class="download_link">
<span>DOWNLOAD MIRROR NUMBER {{ links.number }}</span>
</div>
{% endfor %}
IF you don't want to change HTML, instead of declaring the "def links(self)":
class GameLink(DetailView):
def get_object(self):
return get_object_or_404(Product, slug__iexact=self.kwargs['slug'])
def get_context_data(self, **kwargs):
context = super(GameLink, self).get_context_data(**kwargs)
context['links'] = ProductDownload.objects.filter(is_active=True, product=self.object)
return context