comment on a blog post django - python

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)

Related

Django queryset filter based on slug

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 %}

How to pass 2 arguments to def get_queryset?

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(…) &downarrow;
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.

Filter by string in django

I have 2 models: UserProfile and User_Details and I want to display the details for one user.I think the problem is at the filter and I don't know how to filter after a string,I'm new to django.How can I fix this?
class ShowProfile(APIView):
renderer_classes = [TemplateHTMLRenderer]
template_name = 'profile.html'
def get(self, request, pk, format=None):
details=User_Details.objects.all().filter(user=request.user.username)
serializer = ProfileSerializer2(details, many=True)
pprint.pprint(json.loads(JSONRenderer().render(serializer.data)))
return Response({'fields ': serializer})
def post(self, request):
serializer = CreatePostSerializer(data=request.data)
if not serializer.is_valid():
return Response({'fields': serializer })
user = UserProfile.objects.filter(username=request.user.username).first()
serializer.save(user=user)
pprint.pprint(json.loads(JSONRenderer().render(serializer.data)))
return redirect('mainPage')
Models:
class UserProfile(AbstractUser):
pass
class User_Details(models.Model):
user = models.OneToOneField(UserProfile, on_delete=models.CASCADE)
first_name = models.CharField(max_length=50, blank = True)
last_name = models.CharField(max_length=50, blank=True)
gender = models.CharField(max_length=6, blank=True, default='')
public_info=models.CharField(max_length=100, blank=True, default='')
Template:
{% extends 'base2.html' %}
{% load rest_framework %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-md-3 ">
<div class="list-group ">
Profile
My Posts
</div>
</div>
{% for d in fields %}
{{d.firs_name }}<h1>a</h1>
{% endfor %}
{% endblock %}

Python Django how can't render my variables from views.py on html file

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

Getting ManyToMany field values in template

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 %}

Categories

Resources