I have a simple blog app which has a blog list view and their detail pages that are generated automatically. everything seems to work just fine in local. however after I deployed the app on the server when I click to see the detail page I get a Template does not exist error.
this is my views:
class BlogMain(ListView):
model = BlogPost
template_name = 'Blog/Blog-news.html'
queryset = BlogPost.objects.all()
context_object_name = 'posts'
ordering = ['-published']
paginate_by = 3
def get_context_data(self, **kwargs):
context = super(BlogMain, self).get_context_data(**kwargs)
context['tags'] = BlogPost.tags.all()
return context
class BlogTags(ListView):
model = BlogPost
template_name = 'Blog/Blog-news.html'
context_object_name = 'posts'
def get_queryset(self):
return BlogPost.objects.filter(tags__slug=self.kwargs.get('tag_slug'))
def get_context_data(self, **kwargs):
context = super(BlogTags, self).get_context_data(**kwargs)
context['tags'] = BlogPost.tags.all()
return context
class BlogDetail(DetailView):
model = BlogPost
template_name = 'Blog/Blog-news-detail.html'
context_object_name = 'blog'
slug_url_kwarg = 'the_slug'
slug_field = 'slug'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["related_items"] = self.object.tags.similar_objects()[:3]
return context
this is my urls:
path('blog/', views.BlogMain.as_view(), name="blog-page"),
path('log/tags/<slug:tag_slug>/', views.MaghaleTags.as_view(), name="tagged"),
re_path(r'blog/(?P<the_slug>[-\w]+)/', views.BlogDetail.as_view(), name='post-detail'),
and finally my templates:
{% for post in posts %}
<div class="container-fluid blog-main mb-5">
<a href="{% url 'post-detail' post.slug %}">
<div class="row">
<div class="col-lg-5 pt-5 pb-3 my-5">
<h5>{{ post.title | persianize_digits }}</h5>
<small>
{% for tag in post.tags.all %}
{{ tag.name }}
{% endfor %}
</small>
<br>
</div>
</div>
</a>
</div>
{% endfor %}
I am sure is this the issue with you I'll just share my experience. I named my template blog.html and in the code I wrote Blog.html just starting character capital. It was running great with my local server but when I deployed the website on pythonanywhere.com it gave me the same error template does not exist so I changed the template name to blog.html in the code and it worked. See if you are having this kind of issue.
Related
i want to fetch a blog with a model field which is unique and but when i click on a perticular blog it throw me above mentioned error
here is my views
class Blogs(View):
def get(self, request):
blog_list = Blog.objects.order_by('-joined_date')
return render(request, 'blogs.html',{'blog_list':blog_list})
class ReadBlogs(View):
def get(self, request, title):
readblog = Blog.objects.filter(title=title)
return render(request,'blogs_read.html', {'readblog':readblog})
my model
class Blog(models.Model):
title = models.CharField(max_length=48, blank=False)
urltitle = models.SlugField(max_length=48, blank=False, unique=True)
title_image = models.ImageField(upload_to='blog',blank=True, null=True)
subone = models.CharField(max_length=80, blank=False)
subone_image = models.ImageField(upload_to='blog',blank=True,null=True)
onedes = models.TextField(blank=False)
my html for fetching right blog
<div class="blogs">
{% for blogs in blog_list %}
<a class="products" href="{% url 'blogs:readblog' title=blogs.urltitle %}">
<div class="blog col-4" style="width: 18rem; height:350px">
<img class="img" src="{{ blogs.title_image.url }}" alt="" height="250px" width="100%">
<div class="detail">
<h4 class="title text-center" style="color: #025; font-family:cursive;">{{blogs.title}}</h4>
</div>
</div>
</a>
{% endfor %}
</div>
my url.py
urlpatterns = [
path('blogs/',Blogs.as_view(),name="Blogs"),
path('<slug:title>/',ReadBlogs.as_view(),name="readblog")
]
as you can see mu urltitle is unique slug field so but when i clicked on a particular blog i got above mentioned error any idea what causing error
my template for showing realated field of that blog
<div class="col-11 card">
<div class="blogs">
{% for blog in readblog %}
<h1 class="text-center" style="color: #025; font-family:cursive; margin-top:20px;">{{read.title}}</h1>
{% endfor %}
</div>
</div>
The URL parameter is named title, not url_title:
path('<slug:title>/',ReadBlogs.as_view(),name='readblog')
therefore the .get(…) method should work with title as parameter:
class ReadBlogs(View):
# title ↓
def get(self, request, title):
blog = Blog.objects.filter(title=title)
return render(request,'blogs_read.html',{'blog':blog})
Here blog is a collection of zero, one, or more blogs. If you want to pass a single Blog object, you should fetch a single object, for example with get_object_or_404:
from django.shortcuts import get_object_or_404
class ReadBlogs(View):
def get(self, request, title):
blog = get_object_or_404(Blog, title=title)
return render(request,'blogs_read.html',{'blog':blog})
It might also make more sense to work with a DetailView [Django-doc] to automatically render the item properly:
from django.shortcuts import get_object_or_404
from django.views.generic.detail import DetailView
class ReadBlogs(DetailView):
model = Blog
template_name = 'blogs_read.html'
def get_object(self, *args, **kwargs):
return get_object_or_404(Blog, title=self.kwargs['title'])
template
{% url 'blogs:readblog' title=blogs.urltitle %}
here, you pass title=urltitle, so you actually pass urltitle!
views
# your-code | wrong
class ReadBlogs(View):
def get(self, request, title):
# ======== HERE, TITLE IS ACTUALLY urltitle! ==================
readblog = Blog.objects.filter(title=title)
return render(request,'blogs_read.html', {'readblog':readblog})
# correct
class ReadBlogs(View):
def get(self, request, title):
readblog = Blog.objects.filter(urltitle = title)
return render(request,'blogs_read.html', {'readblog':readblog})
I was coding a song viewing website with Django then suddenly came across this error
MultipleObjectsReturned at /author/Ed Sheeran get() returned more than one Songs -- it returned 2!
I was trying to set up my website such that when users click on the name of the author of any song, they will be redirected to another page where there are songs of that author only. But unfortunately, my code is running into this error.
My models.py:
class Songs(models.Model):
title = models.CharField(max_length = 100)
lyrics = models.TextField()
author = models.CharField(max_length = 100)
track_image = models.CharField(max_length=2083)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('/', kwargs={'pk': self.pk})
My views.py:
def home(request):
context = {
'songs': Songs.objects.all()
}
return render(request, 'home.html', context)
class AuthorSongListView(ListView):
model = Songs
template_name = 'author_songs.html'
context_object_name = 'songs'
paginate_by = 2
def get_queryset(self):
author = get_object_or_404(Songs, author=self.kwargs.get('author'))
return Songs.objects.filter(author=author)
My html:
{% block content %}
<h1 class="mb-3">Songs by {{ view.kwargs.author }}</h1>
{% for song in songs %}
<article class="media content-section">
<div class="media-body">
<div class="article-metadata">
<a class="mr-2" href="{% url 'author-songs' song.author %}">{{ song.author }}</a>
</div>
<h2><a class="article-title" href="{% url 'song-detail' song.id %}">{{ song.title }}</a></h2>
<p class="article-content">{{ song.lyrics }}</p>
</div>
</article>
{% endfor %}
{% endblock content %}
The error is popping up because Model.objects.get(**args) should always return 1 result. If it finds more than 1 result, it throws this error.
In this code:
class AuthorSongListView(ListView):
model = Songs
template_name = 'author_songs.html'
context_object_name = 'songs'
paginate_by = 2
def get_queryset(self):
author = get_object_or_404(Songs, author=self.kwargs.get('author'))
return Songs.objects.filter(author=author)
This is the line that is throwing error
author = get_object_or_404(Songs, author=self.kwargs.get('author'))
# this is trying to fetch Songs for the given author like this
Songs.objects.get(author=self.kwargs.get('author'))
# Since there are multiple songs for the author, this is throwing error.
What you need to do is update the method get_queryset like this:
def get_queryset(self):
return Songs.objects.filter(author=self.kwargs.get('author'))
i am trying to add objects from my model into my CBV, i have a model created so i am trying to pass them to my views, but its not working,tho i have 2 classes created which are Pricing and Pricingservice, i want an inline for a field in Pricingservice which i did, but i dont know how to add both to my view in CBV in the view so as to access them in my template, here is my code below, kindly help me out because i have been battling with this for days, thanks
model.py
class Pricing(models.Model):
plans = models.CharField(max_length=250)
amount = models.CharField(max_length=250)
services = models.CharField(max_length=250)
def __str__(self):
return self.plans
class Pricingservice(models.Model):
pricing = models.ForeignKey(Pricing, default=None, on_delete=models.CASCADE)
services = models.CharField(max_length=250)
def __str__(self):
return self.pricing.plans
admin.py
class PricingserviceAdmin(admin.StackedInline):
model = Pricingservice
#admin.register(Pricing)
class PricingAdmin(admin.ModelAdmin):
inlines = [PricingserviceAdmin]
class Meta:
model = Pricing
views.py
class HomePageView(TemplateView):
template_name = 'pages/home.html'
def get_context_data(self, **kwargs):
context = super(HomePageView, self).get_context_data(**kwargs)
context['Pricing'] = Pricing.objects.all()
return context
template.html
<div class="row">
{% for p in Pricing %}
<div class="col-md-3 ftco-animate">
<div class="pricing-entry pb-5 text-center">
<div>
<h3 class="mb-4">{{ p.plans }}</h3>
<p><span class="price">#{{ p.amount }}</span> <span class="per">/ Month</span></p>
</div>
<ul>
<li>{{ p.services }}</li>
</ul>
<p class="button text-center">Get Offer</p>
</div>
</div>
{% endfor %}
</div>
[] 1
Try this solution:
class HomePageView(ListView):
model = Pricing
template_name = 'pages/home.html'
And then try this template:
{% for pricing in object_list %}
{{pricing.plans}}<br>
{% for service in pricing.pricingservice_set.all %}
{{ service.services }}<br>
{% endfor %}
{% endfor %}
Please add some styling yourself. :)
It would be better to use a ListView. You would need to tell Django what the relevant model for your view is, i.e.:
class HomePageView(ListView):
model = Pricingservice
template_name = 'pages/home.html'
And then in your template, you can use:
{% for pricingservice in pricingservice_list %}
{{ pricingservice.pricing }}
{% endfor %}
I am not sure exactly how your two models differ, but maybe it would be better to merge them?
try this
views.py
class HomePageView(TemplateView):
template_name = 'pages/home.html'
def get_context_data(self, **kwargs):
context = super(HomePageView, self).get_context_data(**kwargs)
context['Pricing'] = Pricing.objects.all()
return context
class PricePageView(ListView):
model = Pricingservice
template_name = 'pages/home.html'
urls.py
path('', HomePageView.as_view(), name='home'),
path('price/', PricePageView.as_view(), name='price'),
template.html
{% for pricingservice in Pricingservice_list %}
<ul>
<li>{{ pricingservice }}</li>
</ul>
{% endfor %}
am not sure this will work but try this if that answer does not work for you
I am developping in Django.
But while I am trying to run my code, I got an ImproperlyConfigured error...
Error:
ImproperlyConfigured at /acl/
PermissionGroupView is missing a QuerySet. Define PermissionGroupView.model, PermissionGroupView.queryset, or override PermissionGroupView.get_queryset().
Views.py:
class PermissionGroupView(LoginRequiredMixin, generic.CreateView):
template_name = 'acl/acl-dashboard.html'
success_url = '/acl/'
def get_context_data(self, **kwargs):
context = super(PermissionGroupView, self).get_context_data(**kwargs)
if self.request.method == 'POST':
context['groups'] = GroupForm(self.request.POST)
if context['groups'].is_valid():
context['groups'].save()
return HttpResponseRedirect(self.get_success_url())
else:
context['groups'] = GroupForm()
return context
Forms.py:
class GroupForm(forms.ModelForm):
class Meta:
model = Group
fields = '__all__'
acl-dashboard.html:
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="col-md-12 grid-margin stretch-card">
<div class="card">
<div class="card-body">
<h4 class="card-title">Enter New Group</h4>
<div class="row">
<div class="col-md-8">
<form class="forms-sample" action="" method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ groups | crispy}}
<button class="btn btn-success mr-2" type="submit">Save</button>
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock content %}
If someone knows how to help me!
As the error said, you need to define either model or queryset. So change your view like this:
class PermissionGroupView(LoginRequiredMixin, generic.CreateView):
model = Group # <-- Here, we defined the model.
template_name = 'acl/acl-dashboard.html'
success_url = '/acl/'
For more details, please see CreateView documentation.
OR, you can add form_class to your view, which will also attach the model name to model attribute of the view:
class PermissionGroupView(LoginRequiredMixin, generic.CreateView):
form_class = GroupForm # <-- Here, we defined the form.
template_name = 'acl/acl-dashboard.html'
success_url = '/acl/'
I have the following code. The product is like this: There's a book list. On each book item is a form. This form saves a post and makes it related to this particular book. When you click a book item, you see a list of posts, all related to this book item. So far the book list works fine, saving post data works fine, and when you click a list, it (the DetailView) shows the list of posts (instead of book description, which is usually how DetailView is used) fine. What's not working is saving the post to be related to the particular book on whom is the form that saves the post. More simply, when you save a post, the post should be related to the book that the form is located in.
I'd really appreciate your help. Thanks!
views.py:
class BookList(ListView):
model = Book
template_name='books/books.html'
class PostForm(ModelForm):
class Meta:
model = Post
# Previously I tried, unsuccessfully, this among others:
# books = Book.objects.filter(book)
# posts = Post.objects.filter(the_book=books)
# model = posts
fields = ['post']
widgets = {
'post': forms.Textarea()
}
def get_context_data(self, **kwargs):
context = super(BookList, self).get_context_data(**kwargs)
context['form'] = BookList.PostForm
return context
def post(self, request, *args, **kwargs):
form = BookList.PostForm(request.POST)
if form.is_valid():
form.save()
return render(request, self.template_name, {'form': form })
class Posts(DetailView):
model = Book
template_name='books/post_create.html'
slug_field = 'id'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
book = self.object
posts = Post.objects.filter(the_book=book)
context['posts'] = posts
return context
models.py:
class Book(models.Model):
book = models.CharField(max_length=1000, blank=False, null=False, default="1")
def __str__(self):
return self.book
class Post(models.Model):
post = models.CharField(max_length=1000, blank=False, null=False)
the_book = models.ForeignKey('Book', on_delete=models.CASCADE, default="1")
date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.post
books.html:
<ul>
{% for book in object_list %}
<div class='ui card'>
<a class="content" href='{% url 'books:posts' book.id %}'>
<div class="header">{{ book }}</div>
</a>
<div class="ui bottom attached button">
<form class='ui form' action='' method='post'> {% csrf_token %}
{{ form.as_p }}
<div class='postbutton'>
<input class='ui button' type="submit" value="Done" />
</div>
</form>
</div>
</div>
{% empty %}
<h5>You don't have any books!</h5>
{% endfor %}
post_create.html (the name will be changed later...):
<ul>
{% for post in posts %}
<div class='ui card'>
<a class="content">
<div class="header">{{ post }}</div>
</a>
</div>
{% empty %}
<h5>You don't have any posts!</h5>
{% endfor %}
Try this: add a book_id hidden input in your form:
<form class='ui form' action='' method='post'> {% csrf_token %}
{{ form.as_p }}
<input type="hidden" name="book_id" value="{{ book.id }}">
<div class='postbutton'>
<input class='ui button' type="submit" value="Done" />
</div>
and use it in your BookList view:
def post(self, request, *args, **kwargs):
form = BookList.PostForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.the_book_id = request.POST['book_id']
post.save()
return render(request, self.template_name, {'form': form })