My comment system in Django is not working as expected - python

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

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'),

Django Blog - I can't add new comment

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

A NameError doing a Product class in views.py at product/1/new

I am doing a Product application for fun, to which I got an error.
The error says that redirect is not defined at line 29 in my views.py file. Here is my views.py file
from django.contrib.auth.models import User
from django.shortcuts import render,get_object_or_404
from .forms import NewProductForm
from .models import Product
# Create your views here.
def home(request):
products = Product.objects.all()
return render(request, 'home.html', {'products': products})
def product_topics(request, pk):
product = get_object_or_404(Product, pk=pk)
return render(request, 'topics.html', {'product': product})
def new_product(request, pk):
product = get_object_or_404(Product, pk=pk)
user = User.objects.first()
if (request.method == 'POST'):
form = NewProductForm(request.POST)
if(form.is_valid()):
product = form.save(commit = False)
product.starter = user
product.save()
return redirect('product_topics',pk=product.pk)
else:
form = NewProductForm()
return render(request, 'new_product.html', {'product': product, 'form': form})
Here's my urls.py file
from django.conf.urls import url
from django.contrib import admin
from inventories import views
urlpatterns = [
url(r'^$', views.home, name='home'),
url(r'^products/(?P<pk>\d+)/$', views.product_topics, name='product_topics'),
url(r'^products/(?P<pk>\d+)/new/$', views.new_product, name='new_product'),
url(r'^admin/', admin.site.urls),
]
And here's the form that I used to create a new product
{% extends 'base.html' %}
{% load widget_tweaks %}
{% block title %}Start a New Topic{% endblock %}
{% block breadcrumb %}
<li class="breadcrumb-item">Products</li>
<li class="breadcrumb-item">{{ product.name }}</li>
<li class="breadcrumb-item active">New topic</li>
{% endblock %}
{% block content %}
<form method="post" novalidate>
{% csrf_token %}
{% for field in form %}
<div class="form-group">
{{ field.label_tag }}
{% render_field field class="form-control" %}
{% if field.help_text %}
<small class="form-text text-muted">
{{ field.help_text }}
</small>
{% endif %}
</div>
{% endfor %}
<button type="submit" class="btn btn-success">Post</button>
</form>
{% endblock %}
What does this error mean, and can you show me how to fix it?
You haven't imported the redirect function. Add this to your views
from django.shortcuts import redirect

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

Cannot see the form input field at all

I would like to collect the content that user input, then change the database using POST method. But i just blank when i clicked post button on the website.
Here's the views.py
class PostTweet(View):
def post(self, request, username):
form = TweetForm(request.POST)
print form.is_valid()
print request.POST
print form.errors
if form.is_valid():
user = User.objects.get(username=username)
tweet = Tweet(text=form.cleaned_data['text'],
user=user,
country=form.cleaned_data['country'])
tweet.save()
return HttpResponseRedirect('/user/'+username)
else:
form = TweetForm()
return render(request, 'profile.html', {'form':form})
class Profile(View):
"""
User Profile page reachable from /user/<username> URL
"""
def get(self, request, username):
params = {}
user = User.objects.get(username = username)
tweets = Tweet.objects.filter(user=user)
params["tweets"] = tweets
params["user"] = user
return render(request, 'profile.html', params)
forms.py
from django import forms
class TweetForm(forms.Form):
text = forms.CharField(widget=forms.Textarea, max_length=160)
country = forms.CharField(widget=forms.HiddenInput(),required=False)
profile.html
{% extends "base.html" %}
{% block content %}
<div class="row clearfix">
<div class="col-md-6 col-md-offset-3 column">
<form id="form" method="POST" action="post/">{% csrf_token %}
<div class="col-md-8 fieldWrapper">
{{ form }}
<span class="input-group-btn">
<button class="btn btn-default" type="submit">Post</button>
</span>
</div>
</form>
</div>
<h3> </h3>
<div class="col-md-12 column">
{% for tweet in tweets %}
<div class="well">
<span>{{ tweet.text}}</span>
</div>
{% endfor %}
</div>
</div>
{% endblock %}
Here's the urls.py
from django.conf.urls import include, url, patterns
from django.contrib import admin
from tweets.views import Index, Profile, PostTweet, HashTagCloud
admin.autodiscover()
urlpatterns = patterns('',
url(r'^$', Index.as_view()),
url(r'^user/(\w+)/$', Profile.as_view()),
url(r'^admin/', include(admin.site.urls)),
url(r'^user/(\w+)/post/$', PostTweet.as_view()),
url(r'^hashTag/(\w+)/$', HashTagCloud.as_view()),
)
Anyone just give me a hint would be appreciated :-)
Adding {{form}} only should not render the field. form is an object with fields as properties. In your html try substituting {{form}} with {{form.text}}
Also you can try passing the object "form" as follows:
return render(request, 'profile.html', form = form)

Categories