Can anybody tell me why django is telling me that template does not exist?
I would like to go from the film_detail.html to film_report.html, when clicking on the "report"-button...
views.py
class FilmReport(LoginRequiredMixin, UpdateView):
model = Report
fields = ["comment", "reporter", "reports"]
# def __str__(self):
# return self.title
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
urls.py
app_name = 'watchlist'
urlpatterns = [
path("", views.films_view, name="board-home"),
path("film/add", FilmAddView.as_view(), name="film-add"),
path("film/<int:pk>/", FilmDetailView.as_view(), name="film-detail"),
path("film/<int:pk>/report", FilmReport.as_view(), name="film-report")
]
film_detail.html
{% extends "board/base.html" %}
{% block content %}
<article class="media content-section">
<img class="rounded-circle film-img" src="/media/{{object.poster}}">
<!-- Mulighet for å ha en "add review"-knapp på siden der hvor filmene vises. -->
<i class="material-icons right">rate_review</i>add review
<i class="material-icons right">report</i>report
<div class="media-body">
<h2 class="film-title">{{ object.title }}</h2>
<p class="film-plot">{{ object.plot }}</p>
</div>
</article>
{% endblock content %}
film_report.html
{% extends "board/base.html" %}
{% block content %}
<h2>Film report</h2>
<!-- <article class="media content-section">
<img class="rounded-circle film-img" src="/media/{{object.poster}}">
<div class="media-body">
<h2 class="film-title">{{ object.title }}</h2>
</div>
</article> -->
{% endblock content %}
You didn't specify template name for your FilmReport class, so django assumed default name. Default name for UpdateView is <model_name>_form.html.
It's not the issue with FilmDetailView, because it's subclassed from DetailView, which is default to <model_name>_detail.html.
Either change name of your template from film_report.html to report_form.html or template_name='film_report.html' in FilmReport. Here's example from django docs and here's more in details about how it works.
Related
this is the error messag am getting in a picture someone should please help me solve this problem i have been on it for the past 3days,
i have a single blog which is handled by multiple author or admin,so i decided to use class based views and when i create a new post gives an error saying i need blog_detail.html,since i dont have detail blog so i created a Detailview then adding my template_name = 'mymainblogpage.html' so once i create new post it will get posted but wont show the post but will only show the pagination,besides i cant search by post id for example http://127.0.0.1:8000/pages/blog/49/ i just get nothing here is my code.
views.py
def blog(request):
blog_post = Blog.objects.all()
ordering = ['-timestamp']
paginator = Paginator(blog_post, 2)
page_request_var = 'page'
page = request.GET.get(page_request_var)
try:
paginated_queryset = paginator.page(page)
except PageNotAnInteger:
paginated_queryset = paginator.page(2)
except EmptyPage:
paginated_queryset = paginator.page(paginator.num_pages)
context = {
'queryset': paginated_queryset,
'page_request_var': page_request_var
}
return render(request, 'pages/blog.html', context)
class BlogDetailView(DetailView):
model = Blog
template_name = 'pages/blog.html'
context_object_name = 'blog'
urls.py
path('blog/', BlogDetailView.as_view(), name='blog'),
path('blog/<int:pk>/', BlogDetailView.as_view(), name='blog-detail'),
models.py
def get_absolute_url(self):
return reverse('blog-detail', kwargs={'pk': self.pk})
blog.html
<br><p></p>
<section class="ftco-section bg-light" id="blog-section">
<div class="container">
<div class="row justify-content-center mb-5 pb-5">
<div class="col-md-10 heading-section text-center ftco-animate">
<h2 class="mb-4">Gets Every Single Updates Here</h2>
<p>Far far away, behind the word mountains, far from the countries Vokalia and Consonantia</p>
</div>
</div>
<div class="container">
<div class="row justify-content-center mb-5 pb-5">
<div class="col-lg-8 ftco-animate">
{% for blog in queryset %}
<h2 class="text-center">{{ blog.title }}</h2>
<div class="meta mb-3 text-center">
<div><h6><span><a href = "">written By {{ blog.user }}</span><small class="date"><i class="icon-clock"></i> {{ blog.timestamp|timesince }} ago</small><a/></h6>
</div>
</div>
<div><small class="icon-eye text-danger">{{ blog.view_count }}</small></div>
<div class="meta mb-3 text-center">
<h5>{% for cat in blog.categories.all %}<span class="btn btn-dark">{{ cat }}</span> {% endfor %}</h5>
</div>
<p class="text-center">{{ blog.overview }}</p>
{% endfor %}
<nav aria-label="pagination">
<ul class="pagination pagination-circle pg-blue">
{% if queryset.has_previous %}
<li class="page-item">Previous</li>
{% endif %}
<li class="page-item active">{{ queryset.number }}</li>
</a>
</li>
{% if queryset.has_next %}
<li class="page-item">Next</li>
{% endif %}
</ul>
</nav>
{% if is_paginated %}
<nav aria-label="pagination">
<ul class="pagination pagination-circle pg-blue">
{% if queryset.has_previous %}
<li class="page-item">Previous</li>
{% endif %}
<li class="page-item active">{{ queryset.number }}</li>
</a>
</li>
{% if queryset.has_next %}
<li class="page-item">Next</li>
{% endif %}
</ul>
</nav>
{% endif %}
</div>
</div>
</div>
</div>
</section>
You pagination isn't showing because you are passing context variable 'page_request_var': page_request_var instead of 'page_request_var': page
so change it because page_request_var is just a string 'page'.
If you need to use class-based list view then
from django.views.generic import ListView
class PostListView(ListView):
queryset = Post.published.all()
context_object_name = 'posts' # by default class list view uses object_list.
paginate_by = 2 # number of objects/posts per page
template_name = 'pages/blog.html' # by default uses <appname>/<modelname>_<view_type>.html
also, I would recommend using different templates for list and detail views because you are just searching the same template using so I think that may be a problem.
I'm making a Post and Comment model by taking reference from internet. i created and Post and Comment model and it looks ok in django admin panel. i can add post and also a comment to any particular post. but getting trouble when I'm trying to display the comment under the post in templates(under post detail views). PLEASE HELP
models.py
class Post(models.Model):
author = models.ForeignKey(User,on_delete=models.CASCADE)
title = models.CharField(max_length=100)
content = RichTextField()
tags = models.CharField(max_length=50,blank=True,null=True)
date_posted = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post-detail',kwargs={'pk':self.pk})
class Comment(models.Model):
post = models.ForeignKey(Post,on_delete=models.CASCADE)
author = models.ForeignKey(User,max_length=50,on_delete=models.CASCADE)
text = models.TextField()
create_date = models.DateTimeField(default=timezone.now)
def get_absolute_url(self):
return reverse('discuss')
views.py
class PostDetailView(DetailView):
model = Post
def add_comment_to_post(request,pk):
return get_object_or_404(Post,pk=pk)
if request.method == "POST":
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.post= post
comment.save()
return redirect('post-detail',pk=post.pk)
else:
form = CommentForm()
return render(request, 'discuss/comment_form.html',{'form':form})
def comment_remove(request,pk):
comment = get_object_or_404(Comment,pk=pk)
post_pk = comment.post.pk
comment.delete()
return redirect('post-detail', pk=post_pk)
post_detail.html
{% extends 'index.html' %}
{% block content %}
<article class="media content-section">
<div class="medaia-body">
<img class="rounded-circle article-img" src="{{ object.author.profile.image.url }}" alt="image not found">
<div class="article-metedata">
<a class="mr-2" href="{% url 'user-posts' object.author.username %}">{{object.author}}</a>
<small class="text-muted">{{ object.date_posted|date:"F d, Y"}}</small>
</div>
<h2 class="article-title">{{ object.title }}</h2>
<img class="query-img" src="{{ object.image.url }}" alt="image not found">
<p class="article-content">{{ object.content|safe }}</p>
</div>
</article>
{% if object.author == user %}
<div class="post-update-delete">
<button class="btn btn-outline-primary">Edit Post</button>
<button class="btn btn-outline-primary">Delete Post</button>
</div>
{% endif %}
<hr>
<a class="btn btn-primary btn-comment" href="{% url 'add_comment_to_post' pk=post.pk %}">Add Comment</a>
<!-- ############################### ABOVE CODE IS WORKING ############################# -->
<!-- ########################## GETTING PROBLEM IN BELLOW CODE ######################### -->
{% for comment in object.comments.all %}
{% if user.is_authenticated %}
{{ comment.create_date }}
{{ comment.text|safe|linebreaks }}
{{ comment.author }}
{% endif %}
{% empty %}
<p>No Comment</p>
{% endfor %}
{% endblock %}
in post_deatil.html i also tried {% for comment in post.comments.all %} but it is also not working
Since you did not specify a related_name=… parameter [Django-doc], the related_name is by default comment_set, so you iterate over the comments with:
{% for comment in object.comment_set.all %}
…
{% endfor %}
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.
I try to query to get all of Topic of Post. Each Post belong multiple Topic. I got this but i don't know how to pass to Template. This is my code. In template i got posts but i can't access topics of single posts. Thank for help.
models.py
class Post(models.Model):
title = models.CharField(unique=True, max_length=121)
content = models.TextField()
published = models.DateField(default=timezone.now)
def __str__(self):
return self.title
class Topic(models.Model):
topic_name = models.CharField(primary_key=True,unique=True, max_length=60)
posts = models.ManyToManyField(Post)
def __str__(self):
return self.topic_name
views.py
def codinglife(request):
posts = Post.objects.filter(topic__topic_name__contains='codinglife') #Get posts belong topic 'codinglife'
context = {
'posts': Post.objects.filter(topic__topic_name__contains='codinglife')
}
# for each post get topic this post belong many topic
for post in posts:
context[post.id] = Topic.objects.filter(posts=post)
return render(request, 'site/topiclistview.html', context)
Template
{% extends "site/base.html" %}
{% block content %}
{% for post in posts %}
<article class="media content-section">
<div class="media-body">
<div class="article-metadata">
<small class="text-muted">{{ post.published }}</small>
{% comment 'need to show topic her' %}
{% endcomment %}
</div>
<h2><a class="article-title" href="#">{{ post.title }}</a></h2>
<p class="article-content">{{ post.content }}</p>
</div>
</article>
{% endfor %}
{% endblock content %}
No need to do anything special in your views (but see below though), you just have to use the reverse relationship:
{% for post in posts %}
<small class="text-muted">{{ post.published }}</small>
<ul>
{% for topic in post.topic_set.all %}
<li>{{ topic.name }}</li>
{% endfor %}
</ul>
<h2><a class="article-title" href="#">{{ post.title }}</a></h2>
<p class="article-content">{{ post.content }}</p>
{% endfor %}
Now this can optimized a bit by using select_related in your view to avoid doing 1+N db queries.
In my site I have 2 sections for users. The user posts page and the profile page. The profile page has all their info on it, so username, description, first/last name, etc. And the user posts page has all their posts on it. However, I want to integrate them together somehow.
Here is some of the code.
Here is the view for the User Posts
class UserPostListView(ListView):
model = Post
template_name = 'mainapp/user_posts.html'
context_object_name = 'posts'
def get_queryset(self):
user = get_object_or_404(User,username=self.kwargs.get('username'))
return Post.objects.filter(author=user).order_by('-published_date')
As you can see, I am returning the specific users posts.
And now here is my profile view
def view_profile(request,pk=None):
if pk:
user_profile = User.objects.get(pk=pk)
else:
user_profile = request.user
context = {'user':user_profile}
return render(request,'mainapp/profile.html',context)
It returns all the user's info.
Here is the HTML code for both the profile and user posts page
{% block content %}
<div class="profile-page-container">
<div class="profile-page-info">
<div class="profile-page-banner">
<div class="profile-page-banner-background">
<!-- <img src="https://cdn.pixabay.com/photo/2017/08/30/01/05/milky-way-2695569_960_720.jpg" alt="{{ user }}'s Background Image" > -->
</div>
<div class="profile-page-banner-text">
<h2 title="{{ user }}" id="username-profile-page">{{ user|safe|linebreaksbr|truncatechars_html:25 }} {% if user.userprofileinfo.verified %} <span class="image-profile-verified"><img draggable="false" title="Verified User" class="verifed" src="{% static 'images\verified.png' %}" alt="verified" width="25" height="25" srcset=""></span> {% endif %}</h2>
<p>{{ user.first_name }} {{ user.last_name }}</p><br>
</div>
</div>
<div class="profile-page-user-desc-box">
<p>{{ user.userprofileinfo.description }}</p>
<p>{{ user.userprofileinfo.website }}</p>
<p>{{ user.userprofileinfo.joined_date |date:"F d Y" }}</p>
</div>
<br>
{% if user.userprofileinfo.image %}
<img class="rounded-circle account-img" src="{{ user.userprofileinfo.image.url }}" alt="{{ user }}'s Profile Picture'">
{% endif %}
</div>
<div class="user-post-user-profile-page">
<h1 title="{{ user }}">Posts</h1>
{% for post in posts %}
<div class="content">
<div class="post">
<h1 class='posttitle'>{{ post.title }}</h1>
<img class="user-image" src="{{ post.author.userprofileinfo.image.url }}" alt="pfp" width="20%" height="20%">
{% if post.published_date %}
<!-- <div class="postdate">
<i class="fas fa-calendar-day"></i> <p>Posted {{ post.published_date|timesince }} ago</p>
</div> -->
<div class="posted-by">
<p>Posted by <strong>{{ post.author }}</strong> {{ post.published_date|timesince }} ago</p>
</div>
{% else %}
<a class="pub-post" href="{% url 'mainapp:post_publish' pk=post.pk %}">Publish</a>
{% endif %}
<p class='postcontent' >{{ post.text|safe|linebreaksbr }}</p>
</div>
</div>
{% endfor %}
</div>
</div>
{% endblock %}
And here is the user_posts page
{% block content %}
<div class="sidebar">
<p class="active" href="#">{{ view.kwargs.username }}</p>
<button class="commentbtn"><a class="aclass" href="#">Connect with {{ view.kwargs.username }}</a></button>
<p>{{ user.userprofileinfo.email }}</p>
<p>Lorem</p>
</div>
{% for post in posts %}
<div class="content">
<div class="post">
<h1 class='posttitle'>{{ post.title }}</h1>
<img class="user-image" src="{{ post.author.userprofileinfo.image.url }}" alt="pfp" width="20%" height="20%">
{% if post.published_date %}
<!-- <div class="postdate">
<i class="fas fa-calendar-day"></i> <p>Posted {{ post.published_date|timesince }} ago</p>
</div> -->
<div class="posted-by">
<p>Posted by <strong>{{ post.author }}</strong> {{ post.published_date|timesince }} ago</p>
</div>
{% else %}
<a class="pub-post" href="{% url 'mainapp:post_publish' pk=post.pk %}">Publish</a>
{% endif %}
<p class='postcontent' >{{ post.text|safe|linebreaksbr }}</p>
</div>
</div>
{% endfor %}
{% endblock %}
I have tried to merge the FBV into the CBV by cutting it and pasting it below the get_queryset method So like this
def get_queryset(self):
#... code here
def view_profile(request,pk=None):
#... code here
However this did not work. I am just curious as to how I can integrate both together so I can have the best of both worlds in one place
EDIT: Here are the models
class UserProfileInfo(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE,max_length=30)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
description = models.CharField(max_length=150)
website = models.URLField(max_length=200)
image = ProcessedImageField(upload_to='profile_pics',
processors=[ResizeToFill(150, 150)],
default='default.jpg',
format='JPEG',
options={'quality': 60})
joined_date = models.DateTimeField(blank=True,null=True,default=timezone.now)
verified = models.BooleanField(default=False)
def __str__(self):
return f'{self.user.username} Profile'
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
and now the post
class Post(models.Model):
author = models.ForeignKey(User,related_name='posts',on_delete=models.CASCADE)
title = models.CharField(max_length=75)
text = models.TextField()
group = models.ForeignKey(Group,null=True,blank=True,related_name='posts',on_delete=models.CASCADE)
created_date = models.DateTimeField(default=timezone.now)
image = models.ImageField(upload_to='post_images',blank=True,null=True)
file = models.FileField(upload_to='post_files',blank=True,null=True)
published_date = models.DateTimeField(blank=True,null=True,auto_now_add=True)
comments_disabled = models.BooleanField(default=False)
NSFW = models.BooleanField(default=False)
spoiler = models.BooleanField(default=False)
tags = TaggableManager()
def __str__(self):
return self.title
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
Also in continuation to Ian answer, if you have a direct relationship between models then you can simply get the posts for the particular user like this:
def view_profile(request,pk=None):
if pk:
user_profile = User.objects.get(pk=pk)
user_posts = Posts.objects.filter(user__id=pk) #<---add these
else:
user_profile = request.user
user_posts = Posts.objects.filter(user__id = request.user.id) #<---add these
context = {
'user':user_profile,
'user_posts':user_posts
}
return render(request,'mainapp/profile.html',context)
A simple class based view for getting a user:
class UserDetailView(DetailView):
model = User
template_name = 'mainapp/profile.html'
context_object_name = 'user'
Relationships (foreign keys) can be followed backwards. Every foreign key has a reverse relationship defined (unless you set reverse_name to +...) it will usually be named <modelname>_set on the model referenced by the foreign key
For example, the following two lines are equivalent
Post.objects.filter(author=user)
user.post_set.all()
This can be used in your profile template
{% for post in user.post_set.all %}
...
{% endfor %}
I am trying to check the currently logged in user against the user who created the page they are looking at. So essentially, if I am logged in I shouldn't able to go to another user's posts/profile and be able to edit it simply by typing in the edit url pattern.
Here is my view:
class UserEditProfileView(LoginRequiredMixin,UpdateView):
login_url = '/login/'
model = UserProfile
fields = [
'first_name',
'profile_pic',
'location',
'title',
'user_type',
'about',
'website',
'twitter',
'dribbble',
'github'
]
template_name_suffix = '_edit_form'
def qet_queryset(self,request):
current_user = request.user.id
url_args = request.resolver_match.kwargs.pk
if current_user != url_args:
reverse('index')
I have the get_queryset function and the if statement inside it to check if the currently logged in user is the owner of the profile they are trying to edit and redirect them if they aren't. However it is not doing anything... How do I go about implementing this?
Update
View:
class UserEditProfileView(LoginRequiredMixin,UpdateView):
login_url = '/login/'
model = UserProfile
form_class = UserProfileForm
template_name = 'users/userprofile_edit_form.html'
def get_object(self):
return User.objects.get(username=self.request.user.username)
def get_success_url(self):
userid = self.kwargs['pk']
return reverse_lazy('users:user_profile',kwargs={'pk': userid})
urls:
from django.conf.urls import url
from users import views
app_name = 'users'
urlpatterns = [
url(r'^$',views.UserListView.as_view(),name='user_list'),
url(r'^(?P<pk>\d+)/$',views.detailprofile,name='user_profile'),
# url(r'^(?P<pk>\d+)/edit$',views.UserEditProfileView.as_view(),name='user_profile_edit'),
url(
regex=r'^profile/$',
view=views.UserEditProfileView.as_view(),
name='profile'
),
]
Update 2
Userprofile_detail.html Template:
{% extends "base.html" %}
{% block content %}
<div class="sidebar-userinfo">
{% if user.userprofile.profile_pic %}
<img class="profile-pic" src="{{ user.userprofile.profile_pic.url }}">
{% else %}
<img class="profile-pic" src="../../../media/profile_pics/default_pro_pic.png">
{%endif%}
<div class="profile-top-info">
<h2 class="profile-name">{{ user.userprofile.first_name }}</h2>
{% if user.userprofile.location %}
<p class="profile-info small-text">{{ user.userprofile.location }}</p>
{% endif %}
</div>
<div class="profile-info-group">
<p class="accent list-text">Title:</p>
<p class="profile-info list-text">{{ user.userprofile.title }}</p>
<p class="accent list-text">Website:</p>
<p class="profile-info list-text">{{ user.userprofile.website }}</p>
<p class="accent list-text">I'm a:</p>
{% if user.userprofile.user_type == '1' %}
<p class="profile-info list-text">Designer</p>
{% elif user.userprofile.user_type == '2' %}
<p class="profile-info list-text">Developer</p>
{% else %}
<p class="profile-info list-text">Both</p>
{% endif %}
{% if user.userprofile.about %}
<p class="accent list-text">About Me:</p>
<p class="profile-info list-text">{{ user.userprofile.about }}</p>
{% endif %}
<p class="accent list-text">Member Since:</p>
<p class="profile-info list-text">{{ user.userprofile.join_date }}</p>
{% if user.userprofile.twitter %}
<p class="accent list-text">Twitter:</p>
<p class="profile-info list-text">{{ user.userprofile.twitter }}</p>
{% endif %}
{% if user.userprofile.dribbble %}
<p class="accent list-text">Dribbble:</p>
<p class="profile-info list-text">{{ user.userprofile.dribbble }}</p>
{% endif %}
{% if user.userprofile.github %}
<p class="accent list-text">Git Hub:</p>
<p class="profile-info list-text">{{ user.userprofile.github }}</p>
{% endif %}
</div>
{% if request.user.is_authenticated %}
<a class="link" href="{% url 'users:user_profile_edit' %}">Edit Profile</a>
{% endif %}
</div>
<div class="content-right">
{% if user.is_authenticated %}
<a class="btn float-right" href="{% url 'feed:new_post' %}">New Post</a>
{% endif %}
{% include 'feed/userpost_list_inner.html' %}
</div>
{% endblock %}
User profile_edit_form.html template:
{% extends "users/base.html" %}
{% block content %}
<div class="form-title">
<h2 class="form-title-text">Edit Profile</h2>
</div>
<div class="user-forms-base">
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<input class="btn" type="submit" value="Save" />
</form>
</div>
{% endblock %}
Sam Bobel is right and here is the solution in code for the profile problem:
forms.py:
class UserSettingsForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = [
'first_name',
'profile_pic',
'location',
'title',
'user_type',
'about',
'website',
'twitter',
'dribbble',
'github'
]
urls.py:
urlpatterns = [
url(
regex=r'^profile/$',
view=views.UserEditProfileView.as_view(),
name='profile'
),
]
views.py:
class UserEditProfileView(LoginRequiredMixin, UpdateView):
form_class = UserProfileForm
template_name = 'users/userprofile_edit_form.html'
def get_object(self):
# Only get the User record for the user making the request
return User.objects.get(username=self.request.user.username)
I would do it a slightly different way. You really don't want those URLs to even exist, because you don't want to tempt the user into changing the number. Instead, I would not pass a PK into the URL at all, and just fetch the current user through overwriting the get_object method to use request.user.id.
See Here for more info
Let me know if clarification would help
You can use a decorator for this. `
def your_decorator(view_func):
def wrapped(request, *args, **kwargs):
.....do your conditions here...if fail redirection takes place here
return view_func(request, *args, **kwargs)
return wrapped
Just use the decorator and it is that simple.