How to insert a second model into my ListView - django

views.py
from django.shortcuts import render, get_object_or_404
from library.models import Game
from .models import Post
from django.views.generic import (
ListView
)
from django.template import context
# Create your views here.
def home(request):
context = {
'recent': Game.objects.all().order_by('post__date_posted')[:5],
'posts': Post.objects.all()
}
return render(request, 'main/home.html', context)
class TitlePostListView(ListView):
model = Post
template_name = 'main/title_posts.html'
context_object_name = 'posts'
def get_queryset(self):
title = get_object_or_404(Game, title=self.kwargs.get('title'))
return Post.objects.filter(game=title).order_by('-date_posted')[:5]
title_posts.html
{% extends "main/base.html" %}
{% load static %}
{% block styles %}
<link rel="stylesheet" type="text/css" href="{% static 'main/title_posts.css' %}">
{% endblock styles %}
{% block content %}
<style>
body {
background-image: url("{{ game.cover_display.url }}");
background-repeat: no-repeat;
background-size: 100% 1000px;
background-color: #171717;
}
</style>
<div class="container margin-top-300">
<div class="row justify-content-center">
<div class="col-3 text-center">
<img src="{{ game.cover.url }}">
</div>
<div class="col">
<p>{{ game.description| safe }}</p>
</div>
</div>
<hr>
{% for post in posts %}
<div class="row">
<div class="col-4 article-column-height text-center">
<img class="article-image-height" src="{{ post.article_image.url }}">
</div>
<div class="col-8 article-column-height">
<h2><a class="article-title" href="#">{{ post.article_title }}</a></h2>
</div>
</div>
<hr>
</div>
{% endfor %}
{% endblock content %}
models.py
class Post(models.Model):
article_title = models.CharField(max_length=60, default="Article Title Place Holder")
content = HTMLField(default="Article Content Pace Holder")
date_posted = models.DateTimeField(default=timezone.now)
game = models.ForeignKey('library.Game', on_delete=models.CASCADE)
article_image = models.ImageField(default='/media/default.png')
class Game(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
cover = models.ImageField()
cover_display = models.ImageField(default='default.png')
developer = models.CharField(max_length=100)
Edit: I have a page that displays posts/articles for a certain video game. Currently my query returns the posts from the Post model for that video game. However, I am unsure of how to also display the video games description and images on that same page. The {{game.cover.url}}, ((game.description}}, and {{game.cover_display.url}} do not show up when I load the page because I am unsure how to also get that specific games objects from the Game model.
{% for post in posts %}
{% with post.game.set.all|first as game %}
<style>
body {
background-image: url("{{ game.cover_display.url }}");
background-repeat: no-repeat;
background-size: 100% 1000px;
background-color: #171717;
}
</style>
<div class="container margin-top-300 black">
<div class="row justify-content-center">
<div class="col-3 text-center">
<img src="{{ game.cover.url }}">
</div>
<div class="col">
<p>{{ game.description| safe }}</p>
</div>
</div>
{% endwith %}
<hr>
<div class="row">
<div class="col-4 article-column-height text-center">
<img class="article-image-height" src="{{ post.article_image.url }}">
</div>
<div class="col-8 article-column-height">
<h2><a class="article-title" href="#">{{ post.article_title }}</a></h2>
</div>
</div>
<hr>
</div>
{% endfor %}

You are using ForeignKey. So use like this in loop
{% with post.game_set.all|first as game %}
<img src="{{ game.url }}" />
{% endwith %}
As you are already filtering by game then only add the game in your get_context_data() method
def get_context_data(self, **kwargs):
context = super(TitlePostListView, self).get_context_data(**kwargs)
context['game'] = get_object_or_404(Game, title=self.kwargs.get('title'))
return context

Related

There was a problem with the button not working

I am a student who wants to be good at Django. The button does not work. If you press the button in detail.html, I want to save the product in DB as if I purchased it. My goal is to get the buyer, date, and product code as written on views.py. However, even if you press the button now, you can't save it in DB. What's the problem?
model.py
class Join(models.Model):
join_code = models.AutoField(primary_key=True)
username = models.ForeignKey(Member, on_delete=models.CASCADE, db_column='username')
product_code = models.ForeignKey(Product, on_delete=models.CASCADE, db_column='product_code')
part_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return str(self.join_code)
class Meta:
ordering = ['join_code']
Join/views
from datetime import timezone
from django.shortcuts import render
from zeronine.models import *
def join_detail(request):
product = Product.objects.all()
if request.method == "POST":
join = Join()
join.product_code = product
join.username = request.user
join.part_date = timezone.now()
join.save()
return render(request, 'zeronine/detail.html', {'product': product})
detail.html
{% extends 'base.html' %}
{% block title %} 상품 상세보기 {% endblock %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-4">
<img src="{{product.image.url}}" width="190%" style="margin-top: 35px;">
</div>
<div class="text-center col" style="margin-top:150px; margin-left:200px;">
<b><h4 class="content" style="margin-bottom: -5px;"><b>{{product.name}}</b></h4></b>
<br>
<div>
<!-- <span>주최자 : <b>{{ product.username }}</b></span><br>-->
<span style="color: #111111">모집기간 : <b>{{ product.start_date }} ~ {{ product.due_date }}</b></span>
</div>
<hr style="margin-top: 30px; margin-bottom: 30px;">
<p><span class="badge badge-dark">가격</span>
{% load humanize %}
{% for designated in designated_object %}
{% if designated.product_code.product_code == product.product_code %}
{{designated.price | floatformat:'0' | intcomma }}원
{% endif %}
{% endfor %}</p>
<span class="badge badge-dark">목표금액</span> {{ product.target_price | floatformat:'0' | intcomma }}원 <br><br>
<p class="badge badge-dark">공동구매 취지
{{product.benefit|linebreaks}}</p>
<p class="badge badge-dark">상세설명
{{product.detail|linebreaks}}</p>
<br>
<form action="" method="post">
{% csrf_token %}
<a onclick="alert('{{ product.name }} 공동구매 참여가 완료되었습니다.');" style="cursor:pointer;">
<form method="POST" action ="{% url 'zeronine:join_detail' %}">
{% csrf_token %}
<div class="form-group">
<button type="submit" action="{% url 'zeronine:join_detail' %}" class="btn btn-primary" style="float: right; background: #637B46; border: white">업로드</button>
</div>
</form>
</a>
</form>
</div>
</div>
</div>
{% endblock %}
I am not sure but you have a form inside a form in your template. maybe that is causing the problem.
also
in the POST section. it is best practice to use
join = Join.objects.create(product_code=product, ....)```

How can i remove videos from later for individual users?

views.py
here in views.py i have tried to make logic for remove any song from watch later but, i am not able to
build logic for it.Basically dont know how to bring watch_id(primary key) of my watch later model.
def deletewatchlater(request):
if request.method=="POSt":
user=request.user
video_id=request.POST['video_id']
# watch_id=request.POST['watch_id']
wat=Watchlater(user=user,video_id=video_id)
wat.delete()
messages.success(request,"Song delete from watch later")
return render(request,'watchlater.html')
def watchlater(request):
if request.method=="POST":
user=request.user
video_id=request.POST['video_id']
watch=Watchlater.objects.filter(user=user)
for i in watch:
if video_id==i.video_id:
messages.success(request,"Song is already added")
break
else:
wl=Watchlater(user=user,video_id=video_id)
wl.save()
messages.success(request,"Song added to watch later")
return redirect(f"/index/subpage/{video_id}")
wl=Watchlater.objects.filter(user=request.user)
ids=[]
for i in wl:
ids.append(i.video_id)
preserved=Case(*[When(pk=pk,then=pos) for pos,pk in enumerate(ids)])
song=Allmusic.objects.filter(sno__in=ids).order_by(preserved)
return render(request,'watchlater.html',{'song':song})
urls.py
I have made post request for it when user clicks button remove from watch later than it will send details of user and song_id and watchlater id
from django.contrib import admin
from django.urls import path
from . import views
urlpatterns = [
path('postComment',views.postComment,name="postComment"),
path('',views.home,name='home'),
path('index/',views.index,name='index'),
path('indexmovie/',views.indexmovie,name='indexmovie'),
path('index/subpage/<str:sno>',views.subpage,name='subpage'),
path('about/',views.about,name='about'),
path('contact/',views.contact,name='contact'),
#User Login Logout Signup
path('signup',views.handleSignup,name='handleSignup'),
path('login',views.handleLogin,name='handleLogin'),
path('logout',views.handleLogout,name='handleLogout'),
path('search/',views.search,name='search'),
#User Saved
path('index/watchlater',views.watchlater,name='watchlater'),
path('index/history',views.history,name='history'),
path('index/likedsongs',views.likedsongs,name='likedsongs'),
path('index/deletewatchlater',views.deletewatchlater,name='deletewatchlater'),
]
watchlater.html
{% extends 'base.html' %}
{% block title %} watch Later {% endblock %}
{% block css %}
<style>
</style>
{% endblock %}
{% block body %}
<h1 style="text-align:center;padding-top: 5%; "> WATCH LATER</h1>
{% if song|length < 1 %}
<h1 style="text-align:center;padding-top: 5%; "> You have not added anything in watch later</h1>
{% endif %}
<div class="container">
{% for i in song %}
<div class="card mb-3" style="max-width: 940px; padding-top: 3%;">
<div class="row no-gutters">
<div class="col-md-4">
<img src='/media/{{i.image}}' class="card-img-top" alt="...">
</div>
<div class="col-md-8">
<div class="card-body">
<h5 class="card-title" style="color: green; font-weight: 550;">Song Name:{{i.name}}</h5>
<h5 class="card-title" style="color: green; font-weight: 550;">Artist Name:{{i.author}}</h5>
<h5 class="card-title" style="color: green; font-weight: 550;">Movie Name:{{i.movie}}</h5>
<h5 class="card-title" style="color: green; font-weight: 550;">Category:{{i.category}}</h5>
<button class="btn btn-outline-danger">Listen Song</button>
<form action="/index/deletewatchlater" method="POST">
{% csrf_token %}
<input type="hidden" name="video_id" value="{{i.sno}}">
<!-- <input type="hidden" name="watch_id" value="{{i.watch_id}}"> -->
<button class="btn btn-danger">Remove from Listen Later</button>
</form>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
{% endblock %}
models.py
from django.db import models
from django.contrib.auth.models import User
from django.utils.timezone import now
from django.contrib.auth.models import User
# Create your models here.
class Allmusic(models.Model):
sno=models.AutoField(primary_key=True)
name=models.CharField(max_length=100,default="")
author=models.CharField(max_length=100,default="")
description=models.TextField(default="")
movie=models.CharField(max_length=100,default="")
category=models.CharField(max_length=100,default="")
subcategory=models.CharField(max_length=100,default="")
image=models.ImageField(upload_to='images', default="")
musicfile=models.FileField(upload_to='music_file', default="")
length=models.CharField(max_length=100,default="")
def __str__(self):
return self.name
class Watchlater(models.Model):
watch_id=models.AutoField(primary_key=True)
user=models.ForeignKey(User,on_delete=models.CASCADE)
video_id=models.CharField(max_length=100000,default="")
class BlogComment(models.Model):
sno=models.AutoField(primary_key=True)
comment=models.TextField()
user=models.ForeignKey(User,on_delete=models.CASCADE)
post=models.ForeignKey(Allmusic,on_delete=models.CASCADE)
parent=models.ForeignKey('self',on_delete=models.CASCADE,null=True)
timestamp=models.DateTimeField(default=now)
class History(models.Model):
history_id=models.AutoField(primary_key=True)
user=models.ForeignKey(User,on_delete=models.CASCADE)
music_id=models.CharField(max_length=100000,default="")
class Likedsongs(models.Model):
like_id=models.AutoField(primary_key=True)
user=models.ForeignKey(User,on_delete=models.CASCADE)
video_id=models.CharField(max_length=100000,default="")
models.py
from django.db import models
from django.contrib.auth.models import User
from django.utils.timezone import now
from django.contrib.auth.models import User
# Create your models here.
class Allmusic(models.Model):
sno=models.AutoField(primary_key=True)
name=models.CharField(max_length=100,default="")
author=models.CharField(max_length=100,default="")
description=models.TextField(default="")
movie=models.CharField(max_length=100,default="")
category=models.CharField(max_length=100,default="")
subcategory=models.CharField(max_length=100,default="")
image=models.ImageField(upload_to='images', default="")
musicfile=models.FileField(upload_to='music_file', default="")
length=models.CharField(max_length=100,default="")
def __str__(self):
return self.name
class Watchlater(models.Model):
watch_id=models.AutoField(primary_key=True)
user=models.ForeignKey(User,on_delete=models.CASCADE)
song_id=models.ForeignKey(Allmusic, on_delete=models.CASCADE)
class BlogComment(models.Model):
sno=models.AutoField(primary_key=True)
comment=models.TextField()
user=models.ForeignKey(User,on_delete=models.CASCADE)
post=models.ForeignKey(Allmusic,on_delete=models.CASCADE)
parent=models.ForeignKey('self',on_delete=models.CASCADE,null=True)
timestamp=models.DateTimeField(default=now)
class History(models.Model):
history_id=models.AutoField(primary_key=True)
user=models.ForeignKey(User,on_delete=models.CASCADE)
song_id=models.ForeignKey(Allmusic, on_delete=models.CASCADE)
class Likedsongs(models.Model):
like_id=models.AutoField(primary_key=True)
user=models.ForeignKey(User,on_delete=models.CASCADE)
song_id=models.ForeignKey(Allmusic, on_delete=models.CASCADE)
watchlater.html
{% extends 'base.html' %}
{% block title %} watch Later {% endblock %}
{% block css %}
<style>
</style>
{% endblock %}
{% block body %}
<h1 style="text-align:center;padding-top: 5%; "> WATCH LATER</h1>
{% if song|length < 1 %}
<h1 style="text-align:center;padding-top: 5%; "> You have not added anything in watch later</h1>
{% endif %}
<div class="container">
{% for i in song %}
<div class="card mb-3" style="max-width: 940px; padding-top: 3%;">
<div class="row no-gutters">
<div class="col-md-4">
<img src='/media/{{i.image}}' class="card-img-top" alt="...">
</div>
<div class="col-md-8">
<div class="card-body">
<h5 class="card-title" style="color: green; font-weight: 550;">Song Name:{{i.name}}</h5>
<h5 class="card-title" style="color: green; font-weight: 550;">Artist Name:{{i.author}}</h5>
<h5 class="card-title" style="color: green; font-weight: 550;">Movie Name:{{i.movie}}</h5>
<h5 class="card-title" style="color: green; font-weight: 550;">Category:{{i.category}}</h5>
<button class="btn btn-outline-danger">Listen Song</button>
<form action="/index/deletewatchlater" method="POST">
{% csrf_token %}
<input type="hidden" name="song_id" value="{{i.sno}}">
<button class="btn btn-danger">Remove from Listen Later</button>
</form>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
{% endblock %}
views.py
def deletewatchlater(request):
if request.method=="POSt":
user=request.user
song_id=request.POST['song_id']
wat=Watchlater.objects.get(song_id=song_id, user=user)
wat.delete()
messages.success(request,"Song delete from watch later")
return render(request,'watchlater.html')
OK I changed your models, view and template.
Changes are these
Creating a foreign key(song_id) in Watchlater, History, Likedsongs models with relationship between AllSongs.
In template we pass {{i.sno}} which is equal to song_id in Watchlater, History, Likedsongs models.
In Your view we get this song_id and filter Watchlater model with these fields(song_id and user) and delete.

how can I access userprofile from another user?

I need some help when I create a user and user profile accordingly and when I try to access to any user by another user the request turns me on the request I work on not the real user, although, I'm using the slug to specify what the user I click on it maybe I can not explain what happens to me exactly for more explanation, please click on that video to show what I mean: https://www.youtube.com/watch?v=MzSo0ay2_Xk&feature=youtu.be
accounts app
models.py
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.template.defaultfilters import slugify
CHOICE = [('male', 'male'), ('female', 'female')]
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
slug = models.SlugField(max_length=100, unique=True, blank=True)
overview = models.TextField(editable=True, blank=True, default='You have no an Overview yet')
city = models.CharField(max_length=20, blank=False)
phone = models.IntegerField(default=0, blank=True)
sex = models.CharField(max_length=10, default='male', choices=CHOICE)
skill = models.CharField(max_length=100, default='You have no skills yet')
logo = models.ImageField(upload_to='images/', default='images/default-logo.jpg', blank=True)
def __str__(self):
return self.user.username
def save(self, *args, **kwargs):
self.slug = slugify(self.user)
super().save(*args, **kwargs)
def create_profile(sender, **kwargs):
if kwargs['created']:
user_profile = UserProfile.objects.create(user=kwargs['instance'])
post_save.connect(receiver=create_profile, sender=User)
view.py
class ViewProfile(UpdateView):
queryset = UserProfile.objects.all()
template_name = 'accounts/profile.html'
form_class = UpdateInfoForm
slug_field = 'slug'
slug_url_kwarg = 'user_slug'
def get_success_url(self):
return reverse_lazy('accounts:view_profile', kwargs={'user_slug': self.request.user.userprofile.slug})
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
user_prof = UserProfile.objects.get(user=self.request.user)
context['user_prof'] = user_prof
context['get_favourite'] = User.objects.get(username=self.request.user.username).favorite.all()
return context
def form_valid(self, form):
form.instance.user_slug = self.request.user.userprofile.slug
self.object = form.save()
return super().form_valid(form)
profile.html
{% extends 'base.html' %}
{% block title %} {{ user.first_name }} {{ user.last_name }} Profile {% endblock %}
{% block body %}
<!-- User Profile Section -->
{% if user.is_authenticated %}
<div class="profile">
<div class="container-fluid">
<div class="col-md-1">
<div class="thumbnail">
<div class="row">
<div class="col-xs-12">
<!-- Profile View Section -->
<div class="logo-image text-center">
{% if user.userprofile.logo %}
<div class="my-image">
{% if request.user.username == user.userprofile.slug %}
<a href="{% url 'accounts:user_image' user.userprofile.slug %}">
<img class="img-responsive" src="{{ user.userprofile.logo.url }}">
</a>
<span>
<a href="{% url 'accounts:add_avatar' user.userprofile.slug %}" class="fa fa-camera fa-1x text-center">
<p>Upload Image</p>
</a>
</span>
{% endif %}
</div>
{% else %}
{% load static %}
<div class="my-image">
<img class="img-responsive img-thumbnail" src="{% static 'index/images/default-logo.jpg' %}">
<span>
<a href="{% url 'accounts:add_avatar' user.userprofile.slug %}" class="fa fa-camera fa-1x text-center">
<p>Upload Image</p>
</a>
</span>
</div>
{% endif %}
<h4>{{ user.first_name }} {{ user.last_name }}</h4>
</div>
</div>
<div class="col-xs-12">
<div class="caption">
<ul class="nav nav-pills nav-stacked">
<li role="presentation" class="active">Overview</li>
<li role="presentation" class="">Personal Information</li>
<li role="presentation" class="">Skills</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<!-- Information Sections -->
<div class="col-md-8 col-md-offset-3 information">
<div class="overview show" id="overview">
<h2 class="line">Overview</h2>
<p class="lead">{{ user.userprofile.overview }}</p>
<a data-placement="bottom" title="update overview" class="fa fa-edit" data-toggle="modal" data-tooltip="tooltip" data-target=".overview_info"></a>
</div>
<div class="personal-info" id="personal-information">
<h2 class="line">Personal Information</h2>
<p class="lead">City: {{ user.userprofile.city }}</p>
<p class="lead">Phone Number: 0{{ user.userprofile.phone }}</p>
<p class="lead">Sex: {{ user.userprofile.sex }}</p>
<a data-placement="bottom" title="update personal information" class="fa fa-edit" data-toggle="modal" data-tooltip="tooltip" data-target=".personal_info"></a>
</div>
<div class="skill" id="my-skills">
<h2 class="line">Skills:</h2>
<p class="lead">{{ user.userprofile.skill }}</p>
<a data-placement="bottom" title="update skills" class="fa fa-edit" data-toggle="modal" data-tooltip="tooltip" data-target=".skills"></a>
</div>
</div>
<!-- get all questions -->
{% if user_prof.userasking_set.all %}
<div class="col-md-8 col-md-offset-3 user_questions">
<h2 class="line">All Questions You Asked</h2>
{% for questions in user_prof.userasking_set.all %}
<p>{{ questions.title }}</p>
{% endfor %}
</div>
{% endif %}
<!-- get favourites -->
{% if get_favourite %}
<div class="col-md-8 col-md-offset-3 user_questions">
<h2 class="line">Favourites</h2>
{% for fav in get_favourite %}
<p>{{ fav.title }}</p>
{% endfor %}
</div>
{% endif %}
</div>
{% include 'accounts/information_form.html' %}
</div>
{% include 'base_footer.html' %}
{% endif %}
{% endblock %}
self.request.user refers to the currently logged in user. That is why you are getting the same result for all users.
To get what you want, you need to make the following change in your views:
user_prof = UserProfile.objects.get(pk=self.kwargs['pk'])
But also, I'm not sure why you are using an UpdateView when you simply want to display objects? You should use TemplateView instead.

How can I sort posts by date in my web application in Django?

I have a web application and I was trying to order it by most recent date, that is, the most current above and the oldest dates below, but for some reason it orders me the other way around and on other computers it orders well, the strange thing is that on my local server it is fine, it orders me as I want but at the time of showing it on the website it shows as I had mentioned before.
models.py
from django.db import models
class Publicacion(models.Model):
foto = models.ImageField()
titulo = models.CharField(max_length=200)
contenido = models.TextField()
fecha = models.DateField(auto_now_add=True)
contenido_largo = models.TextField(max_length=10000, default='', null=True, blank=True)
def __str__(self):
return self.titulo
views.py
class ListarPublicaciones(ListView):
model = Publicacion
template_name = 'Publicacion/listarPublicaciones.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
if self.request.user.is_authenticated:
pedidos = Pedido.objects.filter(cliente = self.request.user).aggregate(Sum('cantidad'))
context['Pedido'] = pedidos
context['object_list'] = Publicacion.objects.all().order_by('-fecha')
return context
I have tried with order_by('-fecha__year','-fecha__month','-fecha__day')
html
<section class="py-5"><!-- Page Content -->
<div class="container"><!-- Container página principal -->
<div class="row">
<div class="col-md-12">
<div class="panel">
{% for p in object_list %}
<div class="row">
<br>
<div class="col-md-3 col-sm-3 text-center">
<a class="story-img" href="{% url 'publicacion:detallePublicacion' p.pk %}">
<img src="{{p.foto.url}}" class="rounded" style="width: 250px;"></a>
</div>
<div class="col-md-8 col-sm-9">
<a class="subt" href="{% url 'publicacion:detallePublicacion' p.pk %}"><h2>{{p.titulo}}</h2></a>
<div class="row">
<div class="col-md-12">
<p class="texto">{{p.contenido|urlize}}</p>
<div class="redes list_op" style="text-align: right;">
<ul class="list-inline list-unstyled" >
{% if p.contenido_largo %}
<li>
<a class="plus" href="{% url 'publicacion:detallePublicacion' p.pk %}">Ver más</a>
</li>
<li>|</li>
{% endif %}
<li>{{p.fecha.day}}-{{p.fecha.month}}-{{p.fecha.year}}</li>
<li>|</li>
<li>
<i class="fa fa-share" aria-hidden="true" style="font-size: 12px; color: #2c5d63;"></i> Compartir:
<a target="_blank" href="http://www.facebook.com/sharer.php?u=http://feriacultiva.com/publicaciones/detallepublicacion/{{p.pk}}"><img src="{% static 'icon/facebook.png' %}" border=0 height="25" class="facebook" /></a>
<img class="whatsapp" border="0" src="{% static 'icon/whatsapp.png' %}">
<img class="twitter" border="0" src="{% static 'icon/twitter.png' %}" height="25">
</li>
</ul>
</div>
</div>
<div class="col-xs-3">
</div>
</div>
<br><br>
</div>
</div>
<hr>
{% endfor %}
</div>
</div>
</div>
</div>
</section>
It can be resolved by using '''DateTimeField'''
Then '''order_by''' will work
Replace and remigrate it works fine for me

How to create a search function on a class-based list view?

I am trying to create a search function based on the title of my posts. Right now I am trying to implement this search using a filter but the list view is not rendering. I am unsure if I should implement a URL for my search function.
This is my model:
class Post(models.Model):
title = models.CharField(max_length=100)
image = models.ImageField(default = 'default0.jpg', upload_to='course_image/')
description = models.TextField()
price = models.DecimalField(decimal_places=2, max_digits=6)
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
feedback = models.ManyToManyField(Feedback)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk' : self.pk})
This is my class-based list view:
class PostListView(ListView):
model = Post
template_name = 'store/sub_home.html' # <app>/<model>_<viewtype>.html
context_object_name = 'posts'
ordering = ['date_posted']
paginate_by = 12
def get_queryset(self):
object_list = super(PostListView, self).get_queryset()
search = self.request.GET.get('q', None)
if search:
object_list = object_list.filter(title__icontains = title)
return object_list
This is my search bar:
<div id="search">
<form method='GET' action=''>
<input type="text" name='q' placeholder="">
<button id='search_holder'>
<img src="/static/store/search_icon.gif" id="search_icon">
</button>
</form>
</div>
This is my html that is rendering the posts:
{% extends "store/base.html" %}
{% block content %}
{% include "store/home_ext.html" %}
<div style="padding-top: 20px;" id="main" >
<section class="text-center mb-4">
<div class="row" id="random">
{% for post in posts %}
{% include "store/card.html" %}
{% endfor %}
</div>
<div class="row" id="subscription" style="display: none;">
{% if not subs %}
<h2>You have not subscribed to any course :/</h2>
{% endif %}
{% for post in subs %}
{% include "store/card.html" %}
{% endfor %}
</div>
<div class="row" id="content" style="display: none;">
{% if not mine %}
<h2>You have not published anything :/</h2>
{% endif %}
{% for post in mine %}
{% include "store/card.html" %}
{% endfor %}
</div>
</section>
{% include "store/pagination.html" %}
</div>
{% endblock content %}
This is my card.html:
{% load extra_filter %}
<div class="col-lg-3 col-md-6 mb-4">
<div id="course_card">
<div class="view overlay">
<img style="margin-left: -10px;" src="{{ post.image.url }}" alt="">
</div>
<div>
<div>
<strong>
{% if user.is_authenticated %}
<a class="title" href="{% url 'post-detail' post.id %}" >
{% else %}
<a class="title" href="{% url 'login' %}" >
{% endif %}
{% if post.title|length < 30 %}
<span>{{ post.title }}</span>
{% else %}
<span>{{ post.title|cut:27 }}</span>
{% endif %}
<span style="background-color: rgb(253, 98, 98);" class="badge badge-pill danger-color">NEW
</span>
</a>
</strong>
</div>
<div class="star-ratings-css">
<div class="star-ratings-css-top" style="width: {{ post.feedback|calc_rating }}%"><span>★</span><span>★</span><span>★</span><span>★</span><span>★</span></div>
<div class="star-ratings-css-bottom"><span>★</span><span>★</span><span>★</span><span>★</span><span>★</span></div>
</div>
<a href="{% url 'user-posts' post.author.username %}" class="author">
by {{ post.author }}
</a>
<div>
<strong style="text-align: right;" class="price">S${{ post.price }}
</strong>
</div>
<small class="date">
{{ post.date_posted|date:'d F y'}}
</small>
</div>
</div>
</div>
As Nalin Dobhal mentioned in comments, context_object_name should be posts not post. Because in template, you are iterating through posts context variable. Also, when using search functionality, the implementation should be like this:
class PostListView(ListView):
model = Post
template_name = 'store/sub_home.html' # /_.html
context_object_name = 'posts'
ordering = ['date_posted']
paginate_by = 12
def get_queryset(self, *args, **kwargs):
object_list = super(PostListView, self).get_queryset(*args, **kwargs)
search = self.request.GET.get('q', None)
if search:
object_list = object_list.filter(title__icontains = search)
return object_list
Because you are sending the search query through URL querystring(ie: url will look like /posts/?q=title in browser). I am using request.GET.get('q') to fetch those query string values, and use it to filter the queryset.