Django Blog - I can't add new comment - python

Problem with a comment system in my Django project.
When I add a new comment in 127.0.0.1:8000 or localhost:8000 the page just reloads and nothing happens.
In "blog/views.py" in post_detail(request, year, month, day, slug): I guess there is something wrong at if request.method == 'POST': and then move on to else: comment_form = CommentForm() so that I can only see the page just reloads. However, I don't know how to fix it...
This is a full code of my Django project.
my github repository
from django.shortcuts import render, get_object_or_404
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.core.mail import send_mail
from django.views.generic import ListView
from taggit.models import Tag
from .models import Post, Comment
from .forms import EmailPostForm, CommentForm
def post_list(request, tag_slug=None):
object_list = Post.published.all()
tag = None
if tag_slug:
tag = get_object_or_404(Tag, slug=tag_slug)
object_list = object_list.filter(tags__in=[tag])
paginator = Paginator(object_list, 3) # 3 posts in each page
page = request.GET.get('page')
try:
posts = paginator.page(page)
except PageNotAnInteger:
# If page is not an integer deliver the first page
posts = paginator.page(1)
except EmptyPage:
# If page is out of range deliver last page of results
posts = paginator.page(paginator.num_pages)
return render(request, 'blog/post/list.html', {'page': page, 'posts': posts})
def post_detail(request, year, month, day, slug):
post = get_object_or_404(Post, slug=slug, status='published', publish__year=year, publish__month=month, publish__day=day)
# List of active comments for this post
comments = post.comments.filter(active=True)
new_comment = None
# Comment posted
if request.method == 'POST':
# A comment was posted
comment_form = CommentForm(data=request.POST)
if comment_form.is_valid():
# Create Comment object but don't save to database yet
new_comment = comment_form.save(commit=False)
# Assign the current post to the comment
new_comment.post = post
# Save the comment to the database
new_comment.save()
else:
comment_form = CommentForm()
return render(request, 'blog/post/detail.html', {'post': post, 'comments': comments, 'new_comment': new_comment, 'comment_form': comment_form})
def post_share(request, post_id):
# Retrieve post by id
post = get_object_or_404(Post, id=post_id, status='published')
sent = False
if request.method == 'POST':
# Form was submitted
form = EmailPostForm(request.POST)
if form.is_valid():
# Form fields passed validation
cd = form.cleaned_data
post_url = request.build_absolute_uri(post.get_absolute_url())
subject = '{} ({}) recommends you reading "{}"'.format(cd['name'], cd['email'], post.title)
message = 'Read "{}" at {}\n\n{}\'s comments: {}'.format(post.title, post_url, cd['name'], cd['comments'])
send_mail(subject, message, 'ecrire06#korea.ac.kr', [cd['to']])
sent = True
else:
form = EmailPostForm()
return render(request, 'blog/post/share.html', {'post': post, 'form': form, 'sent': sent})
class PostListView(ListView):
queryset = Post.published.all()
context_object_name = 'posts'
paginate_by = 3
template_name = 'blog/post/list.html'
{% extends "blog/base.html" %}
{% block title %}{{ post.title }}{% endblock %}
{% block content %}
<!-- title -->
<h1>{{ post.title }}</h1>
<!-- date -->
<p class="date">
Published {{ post.publish }} by {{ post.author }}
</p>
<!-- body-->
{{ post.body|linebreaks }}
<p>
<a href="{% url 'blog:post_share' post.id %}">
Share this post
</a>
</p>
<!-- number of comments-->
{% with comments.count as total_comments %}
<h2>
{{ total_comments }} comment{{ total_comments|pluralize }}
</h2>
{% endwith %}
<!-- content of comments -->
{% for comment in comments %}
<div class="comments">
<p class="font-weight-bold">
Comment {{ forloop.counter }} by {{ comment.name }}
{{ comment.created }}
</p>
{{ comment.body | linebreaks }}
</div>
{% empty %}
<p>There are no comments yet.</p>
{% endfor %}
<!-- add comments -->
<div>
{% if new_comment %}
<h2>Your comment has been added.</h2>
{% else %}
<h2>Add a new comment</h2>
<form methon="post" enctype="multipart/form-data">
{{ comment_form.as_p }}
{% csrf_token %}
<p><input type="submit" value="Add comment"></p>
</form>
{% endif %}
</div>
{% endblock %}

Related

How to solve an exercise 19.1 from the book Python-Crash-Course.-Eric-Mattes

When I try to edit a post I see this error:
TypeError at /edit_post/
edit_post() missing 1 required positional argument: 'post_id'
blogs/models.py
from django.db import models
# Create your models here.
class BlogPost(models.Model):
"""Creating blog topics and text"""
title = models.CharField(max_length=200)
text = models.TextField()
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
"""Retunrning title"""
return self.title
def __str__(self):
"""retunrning text"""
return self.text
blogs/views.py
from django.shortcuts import render, redirect
from .models import BlogPost
from .forms import PostForm
# Create your views here.
def index(request):
"""Homepage for blogs"""
return render(request, 'blogs/index.html')
def posts(request):
"""Shows the blogposts list"""
posts = BlogPost.objects.order_by('-date_added')
context = {'posts': posts}
return render(request, 'blogs/posts.html', context)
def new_post(request):
"""Creating new topic"""
if request.method != 'POST':
#Data didn't sent; create empty form
form = PostForm()
else:
# Data sent POST; process data
form = PostForm(data=request.POST)
if form.is_valid():
form.save()
return redirect('blogs:posts')
# Show empty or invalid form
context = {'form': form}
return render(request, 'blogs/new_post.html', context)
def edit_post(request, post_id):
"""Edit post"""
post = BlogPost.objects.get(id=post_id)
if request.method != 'POST':
# Request; form is filled with the data from current post
form = PostForm(instance=post)
else:
# Sending POST data; process data
form = EntryForm(instance=post, data=request.POST)
if form.is_valid():
form.save()
return redirect(request, 'blogs:posts')
context = {'post': post, 'form': form}
return render(request, 'blogs/edit_post.html', context)
blogs/urls.py
from django.urls import path
from .import views
app_name = 'blogs'
urlpatterns = [
# Homepage
path('', views.index, name='index'),
# Posts
path('posts/', views.posts, name='posts'),
# # View a single post
# path('posts/<int:post_id>/', views.post, name="post"),
# Creating new post
path('new_post/', views.new_post, name='new_post'),
# Edit post
path('edit_post/', views.edit_post, name='edit_post'),
blog/blogs/templates/blogs/base.html
<p>
Blog -
Posts
</p>
{% block content %}{% endblock content %}
</p>
blog/blogs/templates/blogs/posts.html
{% extends "blogs/base.html" %}
{% block content %}
<p>Blogposts</p>
<ul>
{% for post in posts %}
<li>
{{ post }}-
Edit post
</li>
<!-- <li>{{ post }}</li>
--> {% empty %}
<li>No posts have been created yet</li>
{% endfor %}
</ul>
Add a new post:
{% endblock content %}
blog/blogs/templates/blogs/new_post.html
{% extends "blogs/base.html" %}
{% block content %}
<p>Add a new post:</p>
<form action="{% url 'blogs:new_post' %}" method='post'>
{% csrf_token %}
{{ form.as_p }}
<button name="submit">add post</button>
</form>
{% endblock content %}
blog/blogs/templates/blogs/edit_post.html
{% extends "blogs/base.html" %}
{% block content %}
<p>{{ post }}</p>
<p>Edit post</p>
<form action="{% url 'blogs:edit_post' post.id %}"method='post'>
{% csrf_token %}
{{ form.as_p }}
<button name="submit">edit post</button>
</form>
{% endblock content %}
I think you need the post id in your url so as to know which post to edit. Try this in your urls.py:
# Edit post
path('edit_post/<post_id>', views.edit_post, name='edit_post'),

Pagination on DjangO - No Values

I am following a specific guide and basically hit a roadblock I cannot debug.
I implemented Paginator into my blog site and was hoping to show the current page / end of page.
But for some reason the page values are blank.
What would you think is the reason behind this issue? Do you think that this has something to do with my VS compiler not importing paginator properly?
list HTML
pagination block code
<div class="pagination">
<span class="step-links">
{% if page.has_previous %}
Previous
{% endif %}
<span class="current">
Page {{ page.number }} of {{ page.paginator.num_pages }}.
</span>
{% if page.has_next %}
Next
{% endif %}
</span>
</div>
views.py
from django.shortcuts import render, get_object_or_404
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from .models import Post
# Create your views here.
def post_list(request):
object_list = Post.published.all()
paginator = Paginator(object_list, 3) # 3 posts in each page
page = request.GET.get('page')
try:
posts = paginator.page(page)
except PageNotAnInteger:
# If page is not an integer deliver the first page
posts = paginator.page(1)
except EmptyPage:
# If page is out of range deliver last page of results
posts = paginator.page(paginator.num_pages)
return render(request,
'blog/post/list.html',
{'page': page,
'posts': posts})
def post_detail(request, year, month, day, post):
post = get_object_or_404(Post, slug=post,
status='published',
publish__year=year,
publish__month=month,
publish__day=day)
return render(request,
'blog/post/detail.html',
{'post': post})
List HTML Code
{% extends "blog/base.html" %}
{% block title %} My Blog {% endblock %}
{% block content %}
<h1>My Blog</h1>
{% for post in posts %}
<h2>
<a href="{{ post.get_absolute_url }}">
{{ post.title }}
</a>
</h2>
<p class="date">
Published {{ post.publish }} by {{ post.author }}
</p>
{{ post.body|truncatewords:30|linebreaks }}
{% endfor %}
{% include "pagination.html" with page=post %}
{% endblock %}
Github Link
Try using page=posts rather than page=post.
{% include "pagination.html" with page=posts %}

How do I resolve a raise NoReverseMatch(msg) django.urls.exceptions.NoReverseMatch error in Django 3.1 on Mac OS Catalina?

I'm currently going through "Python Crash Course" by Eric Matthes. I'm on Chapter 19 trying to add a page to a web app where users can enter data. If working correctly, the user can write an entry about a topic that he/she is learning about. I wrote the code exactly how the book told me. Sadly I keep getting the following error:
File "/Users/jakeziegelbein/Desktop/crashCoursePython/learning_log/11_env/lib/python3.8/site-packages/django/urls/resolvers.py", line 685, in _reverse_with_prefix
raise NoReverseMatch(msg)
django.urls.exceptions.NoReverseMatch: Reverse for 'learning_logs/new_entry' not found. 'learning_logs/new_entry' is not a valid view function or pattern name.
Here are the files of code:
views.py
from django.shortcuts import render, redirect
from .models import Topic, Entry
from .forms import TopicForm, EntryForm
def index(request):
"""The home page for Learning Log."""
return render(request, 'learning_logs/index.html')
def topics(request):
"""Show all topics."""
topics = Topic.objects.order_by('date_added')
context = {'topics': topics}
return render(request, 'learning_logs/topics.html', context)
def topic(request, topic_id):
"""Show a single topic and all its entries."""
topic = Topic.objects.get(id=topic_id)
entries = topic.entry_set.order_by('-date_added')
context = {'topic': topic, 'entries': entries}
return render(request, 'learning_logs/topic.html', context)
def new_topic(request):
"""Add a new topic."""
if request.method != 'POST':
# No data submitted; create a blank form.
form = TopicForm()
else:
# POST data submitted; process data.
form = TopicForm(data=request.POST)
if form.is_valid():
form.save()
return redirect('learning_logs:topics')
# Display a blank or invalid form.
context = {'form': form}
return render(request, 'learning_logs/new_topic.html', context)
def new_entry(request, topic_id):
"""Add a new entry for a particular topic."""
topic = Topic.objects.get(id=topic_id)
if request.method != 'POST':
# No data submitted; create a blank form.
form = EntryForm()
else:
# POST data submitted; process data.
form = EntryForm(data=request.POST)
if form.is_valid():
new_entry = form.save(commit=False)
new_entry.topic = topic
new_entry.save()
return redirect('learning_logs:topic', topic_id=topic_id)
# Display a blank or invalid form.
context = {'topic': topic, 'form': form}
return render(request, 'learning_logs/new_entry.html', context)
urls.py
"""Defines URL patterns for learning_logs."""
from django.urls import path
from . import views
app_name = 'learning_logs'
urlpatterns = [
# Home page
path('', views.index, name='index'),
# Page that shows all topics.
path('topics/', views.topics, name='topics'),
# Detail page for a single topic.
path('topics/<int:topic_id>/', views.topic, name='topic'),
# Page for adding a new topic
path('new_topic/', views.new_topic, name='new_topic'),
# Page for adding a new entry
path('new_entry/<int:topic_id>/', views.new_entry, name='new_entry'),
]
topic.html
{% extends 'learning_logs/base.html' %}
{% block content %}
<p>Topic: {{ topic }}</p>
<p>Entries:</p>
<p>
Add new entry
</p>
<ul>
{% for entry in entries %}
<li>
<p>{{ entry.date_added|date:'M d, Y H:i' }}</p>
<p>{{ entry.text|linebreaks }}</p>
<p>
Edit entry
</p>
</li>
{% empty %}
<li>There are no entries for this topic yet.</li>
{% endfor %}
</ul>
{% endblock content %}
topics.html
{% extends "learning_logs/base.html" %}
{% block content %}
<p>Topics</p>
<ul>
{% for topic in topics %}
<li>
{{ topic }}
</li>
{% empty %}
<li>No topics have been added yet.</li>
{% endfor %}
</ul>
Add a new topic
{% endblock content %}
newtopic.html
{% extends "learning_logs/base.html" %}
{% block content %}
<p>Add a new topic:</p>
<form action="{% url 'learning_logs:new_topic' %}" method='post'>
{% csrf_token %}
{{ form.as_p }}
<button name="submit">Add topic</button>
</form>
{% endblock content %}
base.html
<p>
Learning Log -
Topics
</p>
{% block content %}{% endblock content %}
new_entry.html
{% extends "learning_logs/base.html" %}
{% block content %}
<p>{{ topic }}</p>
<p>Add a new entry:</p>
<form action="{% url 'learning_logs:new_entry' topic.id %}" method='post'>
{% csrf_token %}
{{ form.as_p }}
<button name='submit'>Add entry</button>
</form>
{% endblock content %}
In your main app's (learning_log project folder) urls.py do you have:
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('learning_logs.urls')),
]

image uploading trouble in django

i have uploaded image but it is not showing up in page.
Uploaded image is also not showing up in media folder.
Used django forms for uploading image.
have a look at my code snippets:
my models.py:
class Post(models.Model):
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
title = models.CharField(max_length=200)
text = models.TextField()
published_date = models.DateTimeField(blank=True, null=True)
blog_img = models.ImageField(upload_to='images/',null=True, blank=True)
#property
def img(self):
if self.blog_img and hasattr(self.blog_img, 'url'):
return self.blog_img.url
else:
return "#"
my views.py:
def post_new(request):
if request.method =="POST":
form = PostForm(request.POST , request.FILES)
if form.is_valid():
post = form.save(commit=False)
post.author= request.user
post.save()
return redirect('post_detail',pk=post.pk)
else:
form=PostForm()
return render(request, 'blog/post_edit.html',{'form':form})
def post_edit(request, pk):
post = get_object_or_404(Post, pk=pk)
if request.method == "POST":
form = PostForm(request.POST, request.FILES, instance=post)
if form.is_valid():
post = form.save(commit=False)
post.author = request.user
post.save()
return redirect('post_detail', pk=post.pk)
else:
form = PostForm(instance=post)
return render(request, 'blog/post_edit.html', {'form': form})
i have added this in settings.py:
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
my post_list.html:
{% extends 'blog/base.html' %}
{% block content %}
<div class="h2">
<h2>Recent Posts</h2>
</div>
{% for post in posts %}
<div class="">
<div class="post">
<h2>{{ post.title }}</h2>
Comments: {{ post.approved_comments.count }}
<img src=" {{ post.img }} " width="200px" alt="images">
<p>{{ post.text|linebreaksbr }}</p>
<div class="date">
<p>published: {{ post.published_date }}</p>
</div>
</div>
</div>
{% endfor %}
{% endblock %}
form template used for getting input from user
django forms are used here..
post_edit.html
{% extends 'blog/base.html' %}
{%block content%}
<h2>New post</h2>
<form method="POST" class="post-form">{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="save btn btn-default">Save</button>
</form>
{%endblock%}

My comment system in Django is not working as expected

I'm creating an application where a user can create their own posts, and other users can comment on the posts.
I have already tried retrieving comments from the database, and displaying them for that certain post, however this has been unsuccessful
Here is my code to tackle this problem:
views.py
def comment(request, pk):
form = CommentForm()
comments = Comment.objects.filter(post=pk)
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
comment = Comment()
comment.body = form.cleaned_data['body']
comment.user = request.user
comment.post = Post.objects.get(pk=pk)
comment.save()
return redirect('home')
return render(request, 'posts/comments.html')
else:
return render(request, 'posts/comments.html', {'error': 'Please submit valid data'})
else:
return render(request, 'posts/comments.html', {'form': form}, {'comments': comments})
comments.html
{% block content %}
<div class="container">
{% for com in comments.all %}
<p>{{ com.body }}</p>
<br>
{% endfor %}
{% if error %}
{{ error }}
<br>
<br>
{% endif %}
<br>
<br>
<br>
<br>
<br>
<form method="post">
<h2> Comment</h2>
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn btn-primary">
Comment</button>
</form>
</div>
{% endblock %}
models.py
class Comment(models.Model):
body = models.CharField(max_length=130)
user = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
def __str__(self):
return self.body
urls.py
path('create/', post_views.Create.as_view(), name='create'),
path('post/<int:pk>/', post_views.DetailPost.as_view(), name='detail'),
path('comment/<int:pk>/', post_views.comment, name='comment'),
urls.py for home
path('admin/', admin.site.urls),
#HOME
path('', post_views.home, name='home'),
This is expected to display a posts comments when a button is pressed to view the post, however the comments do not show. See this here

Categories