How to convert string to CharField - django

In my project there is an opportunity even for unauthorized users to leave a comment to a post. So, I have commentForm:
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ('author', 'text',)
and model:
class Comment(models.Model):
post = models.ForeignKey('blog.Post', on_delete=models.CASCADE, related_name='comments')
author = models.CharField(max_length=200)
text = models.TextField()
If user is authorized, I want to substitute to author fileld username and don't show the input on page, otherwise site visitor should fill this input himself. I've tried to write this in appropriate view:
if request.user.is_authenticated:
form = CommentForm(request.POST, initial={'author': request.user.username})
But form.is_valid is false.
Then I've tried:
if request.user.is_authenticated:
form.fields['author'] = request.user.username
During form validating appeared 'string' object has no attribute 'disabled'.
The question is how to deal with it the right way? Thanks.
post_detail.html
{% extends 'blog/base.html' %}
{% block content %}
<div class="post">
{% if post.published_date %}
<div class="date">
{{ post.published_date }}
</div>
{% else %}
<a class="btn btn-default" href="{% url 'post_publish' post_id=post.pk blog_id=blog.pk %}">Publish</a>
{% endif %}
{% if user.is_authenticated and user == post.blog.author%}
<a class="btn btn-default" href="{% url 'post_remove' post_id=post.pk blog_id=blog.pk %}">удалить</a>
<a class="btn btn-default" href="{% url 'post_edit' post_id=post.pk blog_id=blog.pk %}">редактировать</a>
{% endif %}
<h1>{{ post.title }}</h1>
<p>{{ post.text|safe|linebreaks }}</p>
</div>
<hr>
<p>New comment</p>
<form method="POST" class="post-form">{% csrf_token %}
<!-- HERE I HIDE AUTHOR FIELD FROM LOGGED IN USERS -->
{% if user.is_authenticated %}
{{ form.text }}
{{ form.text.errors }}
{% else %}
{{ form.as_p }}
{% endif %}
<button type="submit" class="save btn btn-default">Send</button>
</form>
{% for comment in post.comments.all %}
<div class="comment">
<div class="date">
{{ comment.created_date }}
<!-- {% if not comment.approved_comment %} -->
<a class="btn btn-default" href="{% url 'comment_remove' post_id=post.pk blog_id=blog.pk com_id=comment.pk %}">удалить</a>
<!-- {% endif %}-->
</div>
<strong>{{ comment.author }}</strong>
<p>{{ comment.text|linebreaks }}</p>
</div>
{% empty %}
<p>No comments here yet :(</p>
{% endfor %}
{% endblock %}
views.py
from .models import Post, Comment, Blog
from django.shortcuts import render
from django.utils import timezone
from django.shortcuts import render, get_object_or_404
from .forms import PostForm, CommentForm, BlogForm
from django.shortcuts import redirect
from django.contrib.auth.decorators import login_required
from django.contrib.auth import logout, login
from django.contrib.auth.models import User
def post_detail(request, blog_id, post_id):
blog = get_object_or_404(Blog, pk=blog_id)
post = get_object_or_404(Post, pk=post_id)
if request.method == "POST":
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
if request.user.is_authenticated:
comment.author = request.user.username
comment.post = post
comment.save()
return redirect('post_detail', blog_id=blog_id, post_id=post.pk)
else:
form = CommentForm()
return render(request, 'blog/post_detail.html', {'post': post, 'blog': blog, 'form': form})
#login_required
def post_publish(request, blog_id, post_id):
post = get_object_or_404(Post, pk=post_id)
post.publish()
return redirect('post_detail', blog_id=blog_id, post_id=post.pk)
#login_required
def post_remove(request, blog_id, post_id):
post = get_object_or_404(Post, pk=post_id)
post.delete()
return redirect('post_list', blog_id=blog_id)
#login_required
def comment_remove(request, blog_id, post_id, com_id):
comment = get_object_or_404(Comment, pk=com_id)
comment.delete()
return redirect('post_detail', blog_id=blog_id, post_id=post_id)
#login_required
def post_edit(request, blog_id, post_id):
post = get_object_or_404(Post, pk=post_id)
if request.method == "POST":
form = PostForm(request.POST, instance=post)
if form.is_valid():
post = form.save(commit=False)
post.author = request.user
post.save()
return redirect('post_detail', blog_id = blog_id, post_id=post.pk)
else:
form = PostForm(instance=post)
return render(request, 'blog/post_edit.html', {'form': form})
def post_list(request, blog_id):
blog = get_object_or_404(Blog, pk=blog_id)
posts = blog.posts.all().filter(published_date__isnull=False).order_by('published_date')
return render(request, 'blog/post_list.html', {'posts': posts, 'blog': blog})

I don't know if this is the best way to solve my problem, but it helped:
change a form value before validation in Django form

Related

how to display a form in function based view

I have got an error when I tried to display a form in function-based view in Django. I could display it in another HTML file and users can make their comments to the blog. But, I think it can be more convenient for users if they can make a comment on the same blog-detail HTML file, so I wanna implement it.
When I tried, this error showed up. "NoReverseMatch at /blogs/blog/30/
Reverse for 'blog' with no arguments not found. 1 pattern(s) tried: ['blogs/blog/(?P[0-9]+)/$']"
Any comments can help me and thanks for your time in advance!!
Here are the codes I wrote...
from django import forms
from .models import Comment
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ('user', 'text',)
#views.py
#login_required
def blog(request, pk):
blog = get_object_or_404(Blog, pk=pk)
form = CommentForm()
# if request.method == 'POST':
# form = CommentForm(request.POST)
# if form.is_valid():
# comment = form.save(commit=False)
# comment.blog = blog
# comment.save()
# return redirect('blog', pk=blog.pk)
# else:
# form = CommentForm()
if blog.link_1 is not None and blog.link_2 is not None:
link_1 = blog.link_1
link_2 = blog.link_2
context = {
'blog': blog,
'link_1': link_1,
'link_2': link_2,
'form': form,
}
elif blog.link_1 is not None or blog.link_2 is not None:
link_1 = blog.link_1
link_2 = blog.link_2
context = {
'blog': blog,
'link_1': link_1,
'link_2': link_2,
'form': form,
}
else:
context = {
'blog': blog,
'form': form,
}
return render(request, 'blog/blog.html', context)
#login_required
def add_comment(request, pk):
blog = get_object_or_404(Blog, pk=pk)
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.blog = blog
comment.save()
return redirect('blog', pk=blog.pk)
else:
form = CommentForm()
context = {
'form': form,
}
return render(request, 'blog/blog.html', context)
#urls.py
path('blog/<int:pk>/', views.blog, name='blog'),
path('blog/<int:pk>/comment/', views.add_comment, name='add_comment'),
#blog.html
{% extends 'base.html' %}
{% block title %}|{{ blog.title }}{% endblock %}
{% block content %}
<div class="header-bar">
← 戻る
</div>
<div class="body-container">
<div class="created-edit-delete">
<p>
{% if request.user == blog.user %}
あなたが{{ blog.created }}に作成</p>
{% else %}
{{ blog.user }}が{{ blog.created }}に作成</p>
{% endif %}
<div class="icons">
{% if request.user == blog.user %}
{% endif %}
</div>
</div>
<h1>{{ blog.title }}</h1>
<p class="blog-content">{{ blog.content_1 }}</p>
{% if blog.content_2 %}
<p class="blog-content">{{ blog.content_2 }}</p>
{% endif %}
{% if blog.content_2 %}
<p class="blog-content">{{ blog.content_3 }}</p>
{% endif %}
<div class="ref-links">
{% if link_1 %}
参考リンク
{% endif %}
{% if link_2 %}
参考リンク
{% endif %}
</div>
<hr>
<div class="comment-area">
<div class="comment-form">
<h2>New comment</h2>
<form action="{% url 'add_comment' blog.id %}" method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="button">追加</button>
</form>
</div>
<div class="comment-all">
{% for comment in blog.comments.all %}
<div class="comment">
<div class="date">{{ comment.created }}</div>
<strong>{{ comment.user }}</strong>
<p>{{ comment.text|linebreaks }}</p>
</div>
{% empty %}
<p>No comments here yet :(</p>
{% endfor %}
</div>
</div>
</div>
{% endblock %}
You have called blog URL here ← 戻る and forgot to pass id inside your URL that's why it's showing this error
NoReverseMatch at /blogs/blog/30/ Reverse for 'blog' with no arguments not found. 1 pattern(s) tried: ['blogs/blog/(?P[0-9]+)/$']
you have to pass id here like this
← 戻る

URL pathfinder in Django - any workaround when it keeps redirecting me to main view?

Sorry for being an embarrassing noob, but I have managed to complete like 99% of the Django Girls tutorial only to realize that there is one essential function in my basic blog site that's not working - the post titles on the main view don't link to their respective post views, even though the code seems alright to me... Guess I am really missing a glaringly obvious mistake! I was considering to switch from pk to slug, could that be an effective workaround?
views.py
from django.shortcuts import render, get_object_or_404
from django.shortcuts import redirect
from django.utils import timezone
from .models import Post
from .forms import PostForm
def post_list(request):
posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date')
return render(request, 'blog/post_list.html', {'posts': posts})
def post_detail(request, pk):
post = get_object_or_404(Post, pk=pk)
return render(request, 'blog/post_detail.html', {'post': post})
def post_new(request):
if request.method == "POST":
form = PostForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.author = request.user
post.published_date = timezone.now()
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, instance=post)
if form.is_valid():
post = form.save(commit=False)
post.author = request.user
post.published_date = timezone.now()
post.save()
return redirect('post_detail', pk=post.pk)
else:
form = PostForm(instance=post)
return render(request, 'blog/post_edit.html', {'form': form})
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.post_list, name='post_list'),
path('post/<int:pk>/', views.post_detail, name='post_detail'),
path('post/new/', views.post_new, name='post_new'),
path('post/<int:pk>/edit/', views.post_edit, name='post_edit'),
]
post_detail.html
{% extends 'blog/base.html' %}
{% block content %}
<article class="post">
<aside class="actions">
{% if user.is_authenticated %}
<a class="btn btn-default" href="{% url 'post_edit' pk=post.pk %}">
{% include './icons/pencil-fill.svg' %}
</a>
{% endif %}
</aside>
{% if post.published_date %}
<time class="date">
{{ post.published_date }}
</time>
{% endif %}
<h2>{{ post.title }}</h2>
<p>{{ post.text|linebreaksbr }}</p>
</article>
{% endblock %}
post_list.html
% extends 'blog/base.html' %}
{% block content %}
{% for post in posts %}
<article class="post">
<time class="date">
{{ post.published_date }}
</time>
<h2>{{ post.title }}</h2>
<p>{{ post.text|linebreaksbr }}</p>
</article>
{% endfor %}
{% endblock %}
Thank you for your patience!

Django creating update post function

I want to create a post update/edit function but I have a problem. When I click "Update" button there is no error but there is no change. I think reason of that a mistake that I made in models.py but I can not figure it out. And here is my code
models.py
class Post(models.Model):
author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
title = models.CharField(max_length=200)
.
.
.
def get_update_url(self):
return reverse('post:post_update', kwargs={'slug': self.slug})
views.py
def post_update(request, slug):
if not request.user.is_authenticated():
return Http404()
post = get_object_or_404(Post, slug=slug)
form = PostForm(request.POST or None, request.FILES or None, instance=post)
if form.is_valid():
form.save()
messages.success(request, "Updated")
return HttpResponseRedirect(get_absolute_url())
context = {
'form': form
}
return render(request, "blog/post_update.html", context)
post_update.html
{% extends 'blog/base.html' %}
{% load crispy_forms_tags %}
{% block body %}
<div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h1>Form</h1>
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form|crispy }}
{{ form.media }}
<input class="btn btn-primary" type="submit" value="Create post">
</form>
</div>
</div>
</div>
{% endblock %}
post_detail.html
//update link
<p >update</p>
urls.py
url(r'^(?P<slug>[\w-]+)/update/$', post_update, name="update"),
forms.py
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ('title', 'text',)
Where is my mistake? What can I do?

nothing happens when submitting django form

I have a problem with django forms, when submitting a form nothing seems to happen, even the server didn't get any response except GET request to view the form template.
here is my code for the forms.py :
from django.forms import ModelForm
from .models import Post
class PostForm(ModelForm):
class Meta:
model = Post
fields = [
"title",
"content",
"category"
]
and here is my post_form.html :
{% extends 'base.html' %}
{% block content %}
<h1>form</h1>
<form method="POST" action=".">
{% csrf_token %}
{{ form.as_p }}
</form>
<button type="submit">Create Post</button>
{% endblock content %}
and here is my handling for the form in views.py :
def post_create(request):
if request.method == "POST":
form = PostForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.save()
return redirect("posts:detail", pk=post.pk)
else :
form = PostForm()
context = {
"form":form,
}
return render(request,"post_form.html", context)
forms.py
from django.forms import ModelForm
from .models import Post
class PostForm(ModelForm):
class Meta:
model = Post
fields = ["title", "content", "category"]
views.py
def post_create(request):
form = PostForm()
if request.method == "POST":
form = PostForm(request.POST)
if form.is_valid():
post = form.save()
return redirect("posts:detail", pk=post.pk)
return render(request,"post-form.html", {"form": form})
post-form.html
{% extends 'base.html' %}
{% block content %}
<h1>form</h1>
{% for error in form.non_field_errors %}
<article class="message is-danger alert-message">
<div class="message-body">
<p>{{ error|escape }}</p>
</div>
</article>
{% endfor %}
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Create Post">
</form>
{% endblock content %}
in your views:
if form.is_valid():
form.commit = False
form.save()
or
if form.is_valid():
form.save(commit=false)
I suggest the latter
Don't Forget Place Your Submit Button In Form Tag !

django security and user control

how to prevent people from editing post and publishing and approving and deleting post of other people who are logined in the system in django.i am creating a forum where anyone can post question.i need help to control users who are already registered in the system
this my post_deatil.html
{% extends 'blog/base.html' %}
{% block content %}
<div class="post">
{% if post.published_date %}
<div class="date">
{{ post.published_date }}
</div>
{% else %}
{% if id.is_authenticated %}
<a class="btn btn-primary" href="{% url 'post_publish' pk=post.pk %}">Publish</a>
<a class="btn btn-danger" href="{% url 'post_remove' pk=post.pk %}"><span class="glyphicon glyphicon-remove"></span></a>
<a class="btn btn-success" href="{% url 'post_edit' pk=post.pk %}"><span class="glyphicon glyphicon-pencil"></span></a>
{% endif %}
{% endif %}
<h1>{{ post.title }}</h1>
<p>{{ post.text|linebreaksbr }}</p>
</div>
<hr>
<a class="btn btn-info" href="{% url 'add_comment_to_post' pk=post.pk %}">Add comment</a>
{% for comment in post.comments.all %}
{% if user.is_authenticated or comment.approved_comment %}
<div class="comment">
<div class="date">
{{ comment.created_date }}
{% if not comment.approved_comment %}
<a class="btn btn-danger" href="{% url 'comment_remove' pk=comment.pk %}"><span class="glyphicon glyphicon-remove"></span></a>
<a class="btn btn-success" href="{% url 'comment_approve' pk=comment.pk %}"><span class="glyphicon glyphicon-ok"></span></a>
Cancel
{% endif %}
</div>
<strong>{{ comment.author }}</strong>
<p>{{ comment.text|linebreaks }}</p>
</div>
{% endif %}
{% empty %}
<p>No comments here yet:</p>
{% endfor %}
{% endblock %}
this my view.py
from django.shortcuts import render
from django.utils import timezone
from .models import Post, Comment
from django.shortcuts import render, get_object_or_404
from .forms import PostForm, CommentForm
from django.shortcuts import redirect
from django.contrib.auth.decorators import login_required
def post_list(request):
posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date')
"""posts = Post.objects.filter(published_date__lte=timezone.now()).get_latest_by('published_date')"""
return render(request, 'blog/post_list.html', {'posts': posts})
def post_detail(request, pk):
post = get_object_or_404(Post, pk=pk)
return render(request, 'blog/post_detail.html', {'post': post})
#login_required
def post_new(request):
form = PostForm()
return render(request, 'blog/post_edit.html', {'form': form})
#login_required
def post_new(request):
if request.method == "POST":
form = PostForm(request.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()
return render(request, 'blog/post_edit.html', {'form': form})
#login_required
def post_draft_list(request):
posts = Post.objects.filter(published_date__isnull=True).order_by('created_date')
return render(request, 'blog/post_draft_list.html', {'posts': posts})
#login_required
def post_publish(request, pk):
post = get_object_or_404(Post, pk=pk)
post.publish()
return redirect('post_detail', pk=pk)
#login_required
def publish(self):
self.published_date = timezone.now()
self.save()
#login_required
def post_remove(request, pk):
post = get_object_or_404(Post, pk=pk)
post.delete()
return redirect('post_list')
#login_required
def post_edit(request, pk):
post = get_object_or_404(Post, pk=pk)
if request.method == "POST":
form = PostForm(request.POST, instance=post)
if form.is_valid():
post = form.save(commit=False)
post.author = request.user
post.published_date = timezone.now()
post.save()
return redirect('post_detail', pk=post.pk)
else:
form = PostForm(instance=post)
return render(request, 'blog/post_edit.html', {'form': form})
#login_required
def add_comment_to_post(request, pk):
post = 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, 'blog/add_comment_to_post.html', {'form': form})
#login_required
def comment_approve(request, pk):
comment = get_object_or_404(Comment, pk=pk)
comment.approve()
return redirect('post_detail', pk=comment.post.pk)
#login_required
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)
You can control it just by checking is authenticated user of session a author of entry.