Im working on my django project. The home page of my project is to show all of my post and category-based post on the bottom after the first part. But my code isnt working and i dont know why. Please help me, im a django noob
#the word Opini is one of my post category
{% for post in blog_posts %}
<div class="card d-inline-flex m-1" style="width: 18rem;">
<a href="{% url 'post-detail' post.pk %}" >
<img class="card-img-top postimg" src="{{ post.post_img.url }}" alt="Card image cap">
</a>
<h3>{{post.category}}</h3>
<div class="card-body">
<h5 class="card-text text-center">{{ post.post_title }}</h5>
<p class="card-text">{{post.post_content|truncatechars:75|safe }}</p>
</div>
</div>
{% endfor %}
<h1> Opini </h1>
{% for post in blog_posts %}
{% if post.category == "Opini" %}
<div class="card d-inline-flex m-1" style="width: 18rem;">
<a href="{% url 'post-detail' post.pk %}" >
<img class="card-img-top postimg" src="{{ post.post_img.url }}" alt="Card image cap">
</a>
<h3>{{post.category}}</h3>
<div class="card-body">
<h5 class="card-text text-center">{{ post.post_title }}</h5>
<p class="card-text">{{post.post_content|truncatechars:75|safe }}</p>
</div>
</div>
{% endif %}
{% endfor %}
{% endfor %}
My Models
class Category(models.Model):
name = models.CharField(max_length=100, unique=True)
class Meta:
verbose_name_plural = "Categories"
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('post_by_category', args=[self.name])
class Post(models.Model):
post_title = models.CharField(max_length=50)
post_img = models.ImageField(upload_to='postImage/')
post_content = RichTextField(blank= True, null = True)
category = models.ForeignKey(Category , on_delete=models.CASCADE)
post_date = models.DateTimeField(auto_now_add=True)
post_author = models.ForeignKey(User, on_delete=models.CASCADE)
class Meta:
ordering = ["-post_date"]
def __str__(self):
return f'{self.post_title}'
When i run the code, only the first page works, when it comes to the second part, nothing appeared
If "Opini" is the category name then you should compare it like this:
{% if post.category.name == "Opini" %}
Related
I am trying to add a notifications feature to my social media platform. Part of this involves adding a notifications logo to my navbar at the top of my website which will display the number of unseen notifications a logged-in user has.
When I run my server, I receive a NameError:
NameError
Here is part of my navbar.html:
{% load custom_tags %}
(...)
{% if user.is_authenticated %}
<div class="nav-item dropdown">
<a class="nav-link dropdown-toggle text-dark" data-bs-toggle="dropdown" href="#" role="button" aria-expanded="false"><i class="fas fa-user"></i></a>
<ul class="dropdown-menu dropdown-menu-end">
<li><a class="dropdown-item" href="{% url 'profile' request.user.profile.pk %}">Profile</a></li>
<li><a class="dropdown-item" href="{% url 'account_logout' %}">Sign Out</a></li>
</ul>
</div>
<div class="nav-item">
{% show_notifications %}
{% endif %}
</div>
</div>
</nav>
Here is my show_notifications.html:
<div class="dropdown">
<span class="badge bg-primary notification-badge">{{ notifications.count }}</span>
<div class="dropdown-content d-none" id="notification-container">
{% for notification in notifications %}
{% if notification.post %}
{% if notification.notification_type == 1 %}
<div class="dropdown-item-parent">
#{{ notification.from_user }} liked your post
<span class="dropdown-item-close">×</span>
</div>
{% elif notification.notification_type == 2 %}
<div class="dropdown-item-parent">
#{{ notification.from_user }} commented on your post
<span class="dropdown-item-close">×</span>
</div>
{% endif %}
{% elif notification.comment %}
{% if notification.notification_type == 1 %}
<div class="dropdown-item-parent">
#{{ notification.from_user }} liked on your comment
<span class="dropdown-item-close">×</span>
</div>
{% elif notification.notification_type == 2 %}
<div class="dropdown-item-parent">
#{{ notification.from_user }} replied to your comment
<span class="dropdown-item-close">×</span>
</div>
{% endif %}
{% else %}
<div class="dropdown-item-parent">
#{{ notification.from_user }} has started following you
<span class="dropdown-item-close">×</span>
</div>
{% endif %}
{% endfor %}
</div>
</div>
Here is my custom_tags.py:
from django import template
from academiciesocial.models import Notification
register = template.Library()
#register.inclusion_tag('social/show_notifications.html', takes_context=True)
def show_notifications(context):
request_user = context['request'].user
notifiations = Notification.objects.filter(to_user=request_user).exclude(user_has_seen=True).order_by('-date')
return {'notifications': notifications}
The final notifications has been marked as "is not defined (PylancereportUndefinedVariable)".
My Notifications class from my models.py:
class Notification(models.Model):
# 1 = Like, 2 = Comment, 3 = Follow
notification_type = models.IntegerField()
to_user = models.ForeignKey(User, related_name='notification_to', on_delete=models.CASCADE, null=True)
from_user = models.ForeignKey(User, related_name='notification_from', on_delete=models.CASCADE, null=True)
post = models.ForeignKey('Post', on_delete=models.CASCADE, related_name='+', blank=True, null=True)
comment = models.ForeignKey('Comment', on_delete=models.CASCADE, related_name='+', blank=True, null=True)
date = models.DateTimeField(default=timezone.now)
user_has_seen = models.BooleanField(default=False)
I am fairly new to this so I would greatly appreciate the exact step-by-step answers to the problem :)
there is typo in your code.
It should be "notifications" you made it "notifiations"
Can you help me with my project.
I 'm trying to go from the page with all the news to a single post, but whatever i stay in page with all news.
But if I write the address o in the address bar, everything works.
Models.py
class News(models.Model):
title = models.CharField(max_length=1000, verbose_name='Название')
slug = models.SlugField(max_length=200, db_index=True)
image = models.ImageField(upload_to='articles/', verbose_name='Фото')
publish = models.DateTimeField(default=timezone.now, verbose_name='Дата публикации')
author = models.ForeignKey(User, related_name='news', on_delete=models.CASCADE, verbose_name='Автор', null=True)
text = models.TextField(verbose_name='Текст')
tags = models.ManyToManyField(Tag, related_name='news', verbose_name='Тэг')
created = models.DateTimeField(auto_now_add=True, verbose_name='Дата создания')
updated = models.DateTimeField(auto_now=True, verbose_name='Дата обнавления')
status = models.CharField(max_length=30, choices=STATUS_CHOICES, default='опубликован', verbose_name='Статус')
class Meta:
ordering = ('title',)
verbose_name = 'Новости'
verbose_name_plural = 'Новости'
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post', kwargs={'post_slug': self.slug})
Views.py
def list_news(request):
news = News.objects.all()
return render(request,
'diplom/news/post.html',
{'news': news})
def single_news(request, post_slug):
post = get_object_or_404(News, slug=post_slug)
return render(request,
'diplom/news/blog-single.html',
{'post': post})
urls.py
urlpatterns = [
path('news/', views.list_news, name='News'),
path('post/<slug:post_slug>/', views.single_news, name='post')
]
templates
<div class="col-lg-4 col-md-6 grid-item">
{% for news in news %}
<div class="blog-item large-item set-bg">{{ news.image }}
<a href="{{post.get_absolute_url}}" methods="post" >
<div class="categories">{{ news.title }}</div>
<h5>{{ news.text| linebreaks|truncatechars:200 }}</h5>
</a>
<div>
{{ news.publish }}
{{ news.tag }}
</div>
</div>
{%endfor%}
</div>
I use the {% url 'url-name' param1 %} for my templates. Does this work when you use it in your template?
URL Reversing
<div class="col-lg-4 col-md-6 grid-item">
{% for post in news %}
<div class="blog-item large-item set-bg">{{ post.image }}
<a href="{% url 'post' post.slug %}">
<div class="categories">{{ post.title }}</div>
<h5>{{ post.text|linebreaks|truncatechars:200 }}</h5>
</a>
<div>
{{ post.publish }}
{{ post.tag }}
</div>
</div>
{%endfor%}
</div>
Also see the name of your single object is the same as your list of objects.
{% for news in news %}
You could rename to post, then change the rest of the variables (not the link) and it should work.
<div class="col-lg-4 col-md-6 grid-item">
{% for post in news %}
<div class="blog-item large-item set-bg">{{ post.image }}
<a href="{{ post.get_absolute_url }}">
<div class="categories">{{ post.title }}</div>
<h5>{{ post.text|linebreaks|truncatechars:200 }}</h5>
</a>
<div>
{{ post.publish }}
{{ post.tag }}
</div>
</div>
{%endfor%}
</div>
</div>
I also updated
<a href="{% url 'post' news.slug %}" methods="post" >
to
<a href="{% url 'post' news.slug %}">
as you are just retrieving the object and not sending information to update it.
Thanks for the answers. The error was in this line.
<a href="{{ post.get_absolute_url }}">
It was necessary to do this
<a href="{{news.get_absolute_url }}">
I am trying to render images from my database to carousel in Django. I have a model which contains url fields to store images url but when I use them in (template.html) my carousel img src, it only renders 1st image but not others even though I have three images url stored in database. To understand it better here is my code.
models.py
from django.db import models
# Create your models here.
class CaraouselData(models.Model):
title = models.CharField(max_length=100, null=False)
description = models.TextField(max_length=200, null=True)
image = models.URLField(null = False, default=True)
def __str__(self):
return self.title
views.py
def home(request):
caraousel_data = CaraouselData.objects.all()
return render(request, 'index.html', context={
'caraousel_data': caraousel_data,
})
template.js
{% block content %}
{# Caraousel Data Section#}
<div class="container-fluid p-0">
<div id="carouselExampleCaptions" class="carousel slide" data-bs-ride="carousel">
<div class="carousel-indicators">
<button type="button" data-bs-target="#carouselExampleCaptions" data-bs-slide-to="0" class="active" aria-current="true" aria-label="Slide 1"></button>
<button type="button" data-bs-target="#carouselExampleCaptions" data-bs-slide-to="1" aria-label="Slide 2"></button>
<button type="button" data-bs-target="#carouselExampleCaptions" data-bs-slide-to="2" aria-label="Slide 3"></button>
</div>
{# images fetching from models #}
<div class="carousel-inner">
{% for item in caraousel_data %}
<div class="carousel-item {% if forloop.counter0 == 0 %} active" {% endif %}>
<img src="{{ item.image }}" width="600" height="670" class="d-block w-100" alt="...">
<div class="carousel-caption d-none d-md-block">
<h5>{{ item.title }}</h5>
<p>{{ item.description }}</p>
</div>
</div>
{% endfor %}
{% endblock %}
I think you have not installed the pillow library.🤔
To handle images you must install them first.
I'm trying to make window where some text will be shown in one language, when clicked second language will appear. I've created one model which consists every information about post.
model.py
from django.db import models
from datetime import datetime
from django.contrib.auth.models import User
def get_default_user():
return User.objects.get(id=1)
class EveryPost(models.Model):
title_pl = models.CharField(max_length=100, blank=True)
title_ru = models.CharField(max_length=100, blank=True)
text_pl = models.TextField(blank=True)
text_ru = models.TextField(blank=True)
date = models.DateTimeField(default=datetime.now, blank=True)
User = models.ForeignKey(User, on_delete=models.CASCADE, default=get_default_user)
def __str__(self):
return self.title_pl
html
{% for obj in EveryPost %}
<div class="card text-center">
<div class="card-header">
<ul class="nav nav-tabs card-header-tabs">
<li class="nav-item">
<a class="nav-link nav-main" href="{% url 'rupl' obj.pk %}">PL</a>
</li>
<li class="nav-item">
<a class="nav-link nav-main" href="{% url 'plru' obj.pk %}">RU</a>
</li>
</ul>
</div>
<div class="card-body">
<h5 class="card-title">{{ obj.title_pl }}</h5>
<p class="card-text">{{ obj.text_pl|truncatechars:350 }}</p>
Zobacz
</div>
<div class="card-footer text-muted">
<span class="float-left">{{ obj.date|date:"d M y" }}</span>
<span class="float-right">Przesłane przez: {{ obj.User }}</span>
</div>
</div>
{% endfor %}
I've tried to make switch between text_pl and text_ru but it wasn't a good idea(lost data)
views.py
def plru(request, pk):
post = EveryPost.objects.get(pk=pk)
post.text_pl = post.text_ru
post.title_pl = post.title_ru
post.save()
return redirect('index')
def rupl(request, pk):
post = EveryPost.objects.get(pk=pk)
post.text_ru = post.text_pl
post.title_ru = post.title_pl
post.save()
return redirect('index')
Image explaining what i want to achieve
there's no need for lot's of functions and urls,
simple is better:
in views.py:
def post_detail(request, post_id):
post = get_or_404(Post, id= post_id)
return render(request, 'post_details.html")
in post_details.html:
<div id="post_in_1st_lng" style="visibility: visible;">
{{ post.title_pl }}
</div>
<div id="post_in_2nd_lng" style="visibility: hidden;">
{{ post.title_ru }}
</div>
<button id="lan_change">Change Language </button>
<script>
$("#lan_change").on('click', function (){
first_vis = $("#post_in_1st_lng").css('visibility') == "visible" ? "hidden" : "visible";
sec_vis = $("#post_in_2nd_lng").css('visibility') == "visible" ? "hidden" : "visible";
$("#post_in_2nd_lng").css('visibility', sec_vis);
$("#post_in_1st_lng").css('visibility', first_vis);
});
</script>
this is a simple jQuery solution.
another way is using ajax, but since the post object is the same one, so text in both languages are already loaded, so no need for time wasting server call.
I fixed it, perhaps it's not most efficient way, but works though :)
I add one extra element in model:
version_pl = models.BooleanField(default=True)
So in HTML it check whether is True or False:
<div class="card-body">
{% if obj.version_pl == False %}
<h5 class="card-title">{{ obj.title_ru }}</h5>
<p class="card-text">{{ obj.text_ru|truncatechars:350 }}</p>
{% else %}
<h5 class="card-title">{{ obj.title_pl }}</h5>
<p class="card-text">{{ obj.text_pl|truncatechars:350 }}</p>
{% endif %}
Zobacz całość
</div>
and views.py
def rupl(request, pk):
post = EveryPost.objects.get(pk=pk)
post.version_pl = True
post.save()
return redirect('index')
def plru(request, pk):
post = EveryPost.objects.get(pk=pk)
post.version_pl = False
post.save()
return redirect('index')
Thanks for replies
Hello Stack Overflow !
I am making a news site in Django as a part of my "internship", I have just started learning web development. I was given a task to make a custom template ( it HAS to be a custom template ) which will render out 3 latest news from a category, and I have to include it as a sidebar on my "article" page.
I tried to write the custom tag, but it's not going to well unfortunately. This is my "last" task for the website, and I'm stuck (like many times before :P )
Here's the thing..everything is working if I include the custom tag on my "list all articles" page, it renders correctly depending on which category I click on.
The thing is, once I try to include my tag into my "single article" page I hit a brick wall. The tag is still working, but is now displaying all of my articles, instead of filtering the articles related to that article's category.
To simplyfiy, If i click on a "health" article to open it, I want the sidebar just to include the articles for the "health" category, I hope that makes sense.
Anyone with a couple of minutes of spare time willing to help me out ? :)
My code :
the custom tag:
from django import template
from news.models import Article
register = template.Library()
#register.inclusion_tag("news/categories.html")
def show_results(article):
article = article.filter()[:3]
return {'article': article}
HTML template for the tag:
{% load article_extras %}
<div class="articles-filter">
<ul>
{% for a in article %}
<img src="{{ a.article_image.url }}" alt="">
<h5>{{ a.title }}</h5>
{% endfor %}
</ul>
</div>
my models :
from django.db import models
from datetime import datetime
from autoslug import AutoSlugField
class Category(models.Model):
category_title = models.CharField(max_length=200, default="")
def __str__(self):
return self.category_title
class Article(models.Model):
title = models.CharField('title', max_length=200, blank=True)
slug = AutoSlugField(populate_from='title', default="",
always_update=True, unique=True)
author = models.CharField('Author', max_length=200, default="")
description = models.TextField('Description', default="")
is_published = models.BooleanField(default=False)
article_text = models.TextField('Article text', default="")
pub_date = models.DateTimeField(default=datetime.now, blank=True)
article_image = models.ImageField('Article Image')
article_category = models.ForeignKey(Category, on_delete="models.CASCADE", default="")
img2 = models.ImageField('Article Image 2', default="", blank=True)
img3 = models.ImageField('Article Image 3', default="", blank=True)
img4 = models.ImageField('Article Image 4', default="", blank=True)
img5 = models.ImageField('Article Image 5', default="", blank=True)
img6 = models.ImageField('Article Image 6', default="", blank=True)
def __str__(self):
return self.title
class Comment(models.Model):
post = models.ForeignKey('Article', on_delete=models.CASCADE, related_name='comments')
author = models.CharField(max_length=200)
text = models.TextField()
created_date = models.DateTimeField(default=datetime.now, blank=True)
approved_comment = models.BooleanField(default=False)
def approve(self):
self.approved_comment = True
self.save()
def __str__(self):
return self.text
the "single article" template where I am trying to include my custom tag:
{% extends "news-base.html" %}
{% load static %}
{% load article_extras %}
{% block article %}
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<div class="preloader d-flex align-items-center justify-content-center">
<div class="spinner">
<div class="double-bounce1"></div>
<div class="double-bounce2"></div>
</div>
</div>
{% show_results article %}
<!-- ##### Post Details Area Start ##### -->
<section class="container post-details-area">
<div class="container single-article-div">
<hr class="hr-single">
<h2 class="single-article-titles">{{ article.title }}</h2>
<hr class="hr-single">
<img class="single-article-img" src="{{ article.article_image.url }}" alt="">
<!-- *********************************** -->
<hr class="hr-single">
<p>Category: {{ article.article_category }}</p>
<hr class="hr-single">
<div class="row justify-content-center">
<!-- Post Details Content Area -->
<div class="col-12 col-xl-8">
<div class="post-details-content bg-white box-shadow">
<div class="blog-thumb">
</div>
<div class="blog-content">
<div class="post-meta">
{{ article.pub_date }}
</div>
<h3 class="single-article-titles post-title"> {{ article.description }}</h3>
<hr>
<!-- Post Meta -->
<div class="post-meta-2">
<i class="fa fa-eye" aria-hidden="true"></i> 1034
<i class="fa fa-thumbs-o-up" aria-hidden="true"></i> 834
<i class="fa fa-comments-o" aria-hidden="true"></i> 234
</div>
<p>{{ article.article_text }}</p>
<hr />
{% include "partials/_thumbnails.html" %}
<hr>
<p>Author: {{ article.author }}</p>
<hr>
{% for comment in article.comments.all %}
<div class="comment">
<div class="date">{{ comment.created_date }}</div>
<strong>{{ comment.author }}</strong>
<p>{{ comment.text|linebreaks }}</p>
</div>
{% empty %}
<p>No comments here yet :(</p>
{% endfor %}
</div>
<!-- Post A Comment Area -->
<div class="post-a-comment-area bg-white mb-30 p-30 box-shadow clearfix">
<!-- Section Title -->
<div class="section-heading">
<h5>LEAVE A REPLY</h5>
</div>
<!-- Reply Form -->
<div class="contact-form-area">
<form action="#" method="post">
<div class="row">
<div class="col-12 col-lg-6">
<input type="text" class="form-control comment-section" id="name" placeholder="Your Name*"
required />
</div>
<div class="col-12 col-lg-6">
<input type="email" class="form-control comment-section" id="email" placeholder="Your Email*"
required />
</div>
<div class="col-12">
<textarea name="message" class="form-control" id="message" cols="30" rows="10"
placeholder="Message*" required></textarea>
</div>
<div class="col-12">
<button class="btn mag-btn comment-section" type="submit">
Submit Comment
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
{% endblock %}
my views.py:
from django.shortcuts import render, reverse, get_object_or_404
from django.views import generic
from news.models import Article, Category
from .forms import CommentForm
from django.http import HttpResponseRedirect
class IndexView(generic.ListView):
template_name = 'news/index.html'
context_object_name = 'latest_article_list'
def get_queryset(self):
return Article.objects.order_by("-pub_date").filter(is_published=True)[:6]
class CategoryView(generic.ListView):
template_name = 'news/categories.html'
context_object_name = 'category'
def get_queryset(self):
return Article.objects.filter(article_category__category_title="Politics")
class ArticlesView(generic.ListView):
context_object_name = 'latest_article_list'
template_name = 'news/articles.html'
paginate_by = 5
def get_context_data(self, **kwargs):
context = super(ArticlesView, self).get_context_data(**kwargs)
context['categories'] = Category.objects.all()
return context
def get_queryset(self):
category_pk = self.request.GET.get('pk', None)
if category_pk:
return Article.objects.filter(article_category__pk=category_pk).order_by("-pub_date")
return Article.objects.order_by("-pub_date")
def article(request, article_id):
article = get_object_or_404(Article, pk=article_id)
context = {'article': article}
return render(request, 'news/article.html', context)
def add_comment_to_article(request, pk):
article = get_object_or_404(Article, pk=pk)
if request.method == "POST":
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.post = article
comment.save()
return HttpResponseRedirect(reverse('news:article', kwargs={"article_id": article.pk}))
else:
form = CommentForm()
return render(request, 'news/add_comment_to_article.html', {'form': form})
my "all articles" page:
<div class="container">
{% block articles %}
<!-- ***************************************** -->
<div class="category-filter container">
<ul>
<li class="categories-title">Categories:</li>
<hr class="small-line">
{% for category in categories %}
<li class="category-list">
{{ category.category_title }}
</li>
{% endfor %}
</ul>
</div>
<!-- ***************************************** -->
{% show_results latest_article_list %}
<hr class="hr-style1">
<h2 class="article-list-title">Article List :</h2>
<hr class="hr-style2">
<div class="container list-wrapper">
{% for article in latest_article_list %}
<div class="container">
<div class="well">
<div class="media">
<a class="pull-left" href="{% url 'news:article' article.id %}">
<img class="media-object" src="{{ article.article_image.url }}">
</a>
<div class="media-body">
<h4 class="media-heading">{{ article.title }}
</h4>
<p class="text-right">{{ article.author }}</p>
<p>{{ article.description }}</p>
<ul class="list-inline list-unstyled">
<li><span><i class="glyphicon glyphicon-calendar"></i> {{ article.pub_date }}
</span></li>
<li>|</li>
<span><i class="glyphicon glyphicon-comment"></i> 2 comments</span>
<li>|</li>
<li>
<span class="glyphicon glyphicon-star"></span>
<span class="glyphicon glyphicon-star"></span>
<span class="glyphicon glyphicon-star"></span>
<span class="glyphicon glyphicon-star"></span>
<span class="glyphicon glyphicon-star-empty"></span>
</li>
<li>|</li>
<li>
<span><i class="fa fa-facebook-square"></i></span>
<span><i class="fa fa-twitter-square"></i></span>
<span><i class="fa fa-google-plus-square"></i></span>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
Thank you so much for taking the time to read this.
Have a good day !
Your changed code wouldn't work at all on the single article page; you would get an AttributeError.
The problem is that you are in your list view you are passing the queryset, latest_article_list, but in the single article view you are passing that single article. You can't filter an article, you can only filter a queryset.
Really it seems that the thing you want to do is to pass a category. There's no reason to pass the latest article list to that template tag; you can just get the articles directly in the tag. But from the single article view you want to get the articles with the same category. So, make the parameter category, and make it optional.
#register.inclusion_tag("news/categories.html")
def show_results(category=None):
articles = Article.objects.all()
if category:
articles = articles.filter(category=category)
return {'article': article[:3]}
Now from the list view you can just call the tag without arguments:
{% show_results %}
whereas from the single view you can pass the article category:
{% show_results article.category %}