Django comment saving to DB but not to post - python

Comments are saving to DB but not linking to Post, unless I manually go to Admin page and link.
MODELS.PY
class Post(models.Model):
title = models.CharField(max_length=50)
description = models.CharField(max_length=50)
info = models.TextField(max_length=2000)
slug = models.SlugField(null=True, unique=True, max_length=300)
created = models.DateField(null=True, auto_now_add=True)
approved = models.BooleanField(default=False, blank=True)
id = models.UUIDField(default=uuid.uuid4, unique=True, primary_key=True, editable=False)
class Comment(models.Model):
post = models.ForeignKey(Post, related_name="comments", on_delete=models.CASCADE, null=True)
name = models.CharField(max_length=50, verbose_name="Name")
comment = models.TextField(max_length=500, verbose_name="Comment")
created = models.DateField(null=True, auto_now_add=True)
approved = models.BooleanField(default=False, blank=True)
id = models.UUIDField(default=uuid.uuid4, unique=True, primary_key=True, editable=False)
FORMS.PY
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ['name','comment']
VIEWS.PY
def create_comment(request, slug):
form = CommentForm()
post = Post.objects.get(slug=slug)
if request.method == "POST":
form = CommentForm(request.POST)
comment = form.save()
comment.post = post
comment.save()
messages.success(request, 'Your comment was successfully submitted!')
return render(request, 'post.html', {'post': post, 'form':form})
return render(request, 'post.html', {'post': post, 'form':form})
From Admin page I can add comment and manually link to post, but from frontend form, comment is created and saved to DB but not linked to any post. Any idea what I'm doing incorrectly?

Where does this review object instance come from, woudn't it be the comment object?
Also, check if the the form is valid:
def create_comment(request, slug):
form = CommentForm()
post = Post.objects.get(slug=slug)
if request.method == "POST":
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save()
comment.post = post
comment.save()
messages.success(request, 'Your comment was successfully submitted!')
return render(request, 'post.html', {'post': post, 'form':form})
return render(request, 'post.html', {'post': post, 'form':form})

Related

how to prevent user from submitting the same form twice

I have the codes below in my views and models. But I want a situation in which a user cannot submit the same form twice. once a user submits the form he or she can only see a preview of what has been submitted but is unable to submit the same form.
Any help would be highly appreciated. Thanks
#views.py
def index(request):
form = MembershipForm()
if request.method == 'POST':
form = MembershipForm(request.POST)
if form.is_valid():
form.save()
return redirect("home")
return render(request, 'index.html', {'form': form)
#models.py
class Membership(models.Model):
fullname = models.CharField(max_length=500, blank=True, null=True)
location = models.IntegerField(default='0',blank=True, null=True)
department = models.IntegerField(default='0',blank=True, null=True)
last_update = models.DateTimeField(auto_now_add=False, auto_now=True)
def __str__(self):
return str(self.fullname)

How to set post_id to resolve error : 'django.db.utils.IntegrityError: NOT NULL constraint failed: posts_comment.post_id'?

I am using Django and attempting to add commenting functionality with AJAX. When I click on the submit button for the comment, the action is not being performed and I am instead seeing a 'django.db.utils.IntegrityError: NOT NULL constraint failed: posts_comment.post_id' error in the terminal. I have checked my models.py file but am unable to identify the cause of this issue. Could you please provide guidance on how to resolve this error?
model.py
class Comment(MPTTModel):
author = models.ForeignKey(User, related_name='author',
on_delete=models.CASCADE, default=None, blank=True)
parent = TreeForeignKey('self', on_delete=models.CASCADE,
null=True, blank=True, related_name='children')
post = models.ForeignKey(Post ,related_name='comments', on_delete=models.CASCADE)
body = models.TextField()
create_date = models.DateTimeField(auto_now_add=True)
status = models.BooleanField(default=True)
view.py
def single_post(request ,*args, **kwargs):
slug=kwargs.get('slug')
print(slug,'slug')
pk=kwargs.get('pk')
print(pk,'pk')
post = get_object_or_404(Post,pk=pk,slug=slug)
allcomments = post.comments.filter(status=True)
comment_form = CommentForm()
return render(
request,
'posts/post_test.html',
{ 'post': post,
'comment_form': comment_form,
'allcomments': allcomments,
}
)
def addcomment(request):
if request.method == 'POST':
comment_form = CommentForm(request.POST)
print(comment_form)
if comment_form.is_valid():
user_comment = comment_form.save(commit=False)
result = comment_form.cleaned_data.get('body')
user = request.user.username
user_comment.author = request.user
user_comment.save()
return JsonResponse({'result2': result, 'user': user})
urls.py
urlpatterns = [
path('test/<int:pk>/<str:slug>/',views.single_post,name ='post_detail'),
path('commented/',views.addcomment,name='addcomment'),
]
if more information is require than tell me in a comments session. I will update my question with that information.
Thank you !
Well I have update my url
form path('commented/',views.addcomment,name='addcomment'),
to path('commented/<int:pk>/<str:slug>/',views.addcomment,name='addcomment'),
than i also updated the add comment function
from
view.py
def addcomment(request):
if request.method == 'POST':
comment_form = CommentForm(request.POST)
print(comment_form)
if comment_form.is_valid():
user_comment = comment_form.save(commit=False)
result = comment_form.cleaned_data.get('body')
user = request.user.username
user_comment.author = request.user
user_comment.save()
return JsonResponse({'result2': result, 'user': user})
to :
views.py
def addcomment(request,*args, **kwargs):
slug=kwargs.get('slug')
print(slug,'slug')
pk=kwargs.get('pk')
print(pk,'pk')
print(request,'request')
post = get_object_or_404(Post,pk=pk,slug=slug)
if request.method == 'POST':
comment_form = CommentForm(request.POST)
print(comment_form,'postting')
if comment_form.is_valid():
user_comment = comment_form.save(commit=False)
result = comment_form.cleaned_data.get('body')
user = request.user.username
user_comment.author = request.user
user_comment.post = post
user_comment.save()
return JsonResponse({'result2': result, 'user': user})
Than it works for me perfectly.

Get currently logged user to Comment Form

I have a Comment Form for my django project, which has a two columns: Author, Text.
I would like to make a author to be the currently looged user and be not able to edit that value. Is there a way to do it?
Here are my codes
forms.py
class CommentForm(forms.ModelForm):
author = forms.CharField(label = "名前", max_length=10,
widget=forms.TextInput(attrs={'style': 'position: relative;left: 0px;'}))
class Meta:
model = Comment
fields = ('author', 'text',)
views.py
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})
models.py
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()
created_date = models.DateTimeField(default=timezone.now)
approved_comment = models.BooleanField(default=False)
def approve(self):
self.approved_comment = True
self.save()
def __str__(self):
return self.text

Django view redirect NoReverseMatch error

In Django project I have error NoReverseMatch after form save, redirecting to "parent view"
models.py
This is a models code - personnel
class Personnel(models.Model):
ID_Personnel = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
NameFirst = models.CharField(max_length=50)
NameLast = models.CharField(max_length=50)
IsActive = models.BooleanField(default=True, editable=True)
TimeCreation = models.DateTimeField(default=datetime.now, editable=False)
class IdentityDocument(models.Model):
ID_IdentityDocument = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
ID_Personnel = models.ForeignKey(Personnel, on_delete=models.PROTECT)
NumberSerial = models.CharField(max_length=50)
DateIssue = models.DateField(null=True)
DateExpiration = models.DateField(null=True)
NameIssuer = models.CharField(max_length=100, null=True)
IsActive = models.BooleanField(default=True, editable=True)
TimeCreation = models.DateTimeField(default=datetime.now, editable=False)
views.py - personnel
def personnel_edit(request, pk):
person = get_object_or_404(Personnel, ID_Personnel=pk)
if request.method == 'POST':
form = PersonnelForm(request.POST, instance=person)
if form.is_valid():
person = form.save(commit=False)
person.save()
return redirect('personnel_detail', pk=person.ID_Personnel)
else:
form = PersonnelForm(instance=person)
return render(request, 'personnel/personnel_edit.html', {'form': form})
def personnel_detail(request, pk):
person = get_object_or_404(Personnel, ID_Personnel=pk)
try:
document = IdentityDocument.objects.filter(ID_Personnel=pk).order_by('ID_IdType', '-DateExpiration').distinct(
'ID_IdType')
except IdentityDocument.DoesNotExist:
document = None
return render(request, 'personnel/personnel_detail.html',
{'person': person, 'document': document})
views.py - Setting ID_Personnel in Form
def identitydocument_new(request, fkey):
if request.method == 'POST':
form = IdentityDocumentForm(request.POST)
if form.is_valid():
iddoc = form.save(commit=False)
iddoc.ID_Personnel = Personnel.objects.get(ID_Personnel=fkey)
iddoc.save()
return redirect('personnel_detail', pk=fkey)
else:
form = IdentityDocumentForm()
return render(request, 'personnel/identitydocument_edit.html', {'form': form})
def identitydocument_edit(request, pk):
doc = get_object_or_404(IdentityDocument, ID_IdentityDocument=pk)
if request.method == 'POST':
form = IdentityDocumentForm(request.POST, instance=doc)
if form.is_valid():
doc = form.save(commit=False)
doc.save()
return redirect('personnel_detail', pk=doc.ID_Personnel)
else:
form = IdentityDocumentForm(instance=doc)
return render(request, 'personnel/identitydocument_edit.html', {'form': form})
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.personnel_list, name='personnel_list'),
path('personnel/<uuid:pk>/', views.personnel_detail, name='personnel_detail'),
path('personnel/new', views.personnel_new, name='personnel_new'),
path('personnel/<uuid:pk>/edit/', views.personnel_edit, name='personnel_edit'),
path('personnel/identitydoc/<uuid:fkey>/', views.identitydocument_new, name='identitydocument_new'),
path('personnel/identitydoc/<uuid:pk>/edit/', views.identitydocument_edit, name='identitydocument_edit'),
]
Form creates new documents and saveing it fine, but after editing it brings NoReverseMatch error.
Traceback
As that error shows, ID_Personnel is a reference to the entire related Personnel document. The URL needs the ID of that object. So you should do:
return redirect('personnel_detail', pk=doc.ID_Personnel_id)
But fundamentally this is a sign that your field name is incorrect. As I say, that is a reference to the object, not an ID, so it shouldn't have a name that implies it's an ID. Just call it Personnel. (Also, Python style is to use lower_case_with_underscore for attributes, so really it should be just personnel.)
Try this
from django.urls import reverse
redirect(reverse('personnel_detail', kwargs={'pk': doc.ID_Personnel}))

Django how to change forms or views.py?

i create simple page where i can add article (title, text and category). When i do it on 'site administration everything is ok', but when i add it on page i can't choose category.
http://i.stack.imgur.com/4Nxzb.jpg
I choose category, for example like on this screen but my article do not have this category after i save it (article is uncategorized).
I created forms.py file and i done it like this:
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ('title', 'text', 'categories')
How must i change 'categories' here to make it usable?
models.py:
from django.db import models
from django.utils import timezone
class Category(models.Model):
name = models.CharField('Nazwa Kategorii', max_length=100)
slug = models.SlugField('Odnośnik', max_length=100)
icon = models.ImageField('Ikonka Kategorii', upload_to='icons',
blank=True)
class Meta:
verbose_name = "Kategoria"
verbose_name_plural = "Kategorie"
def __unicode__(self):
return self.name
class Post(models.Model):
author = models.CharField(max_length=25, blank=True, null=True)
title = models.CharField(max_length=200)
slug = models.SlugField('Odnośnik', max_length=255)
text = models.TextField()
published_date = models.DateTimeField(
default=timezone.now)
categories = models.ManyToManyField(Category, verbose_name='Kategorie')
def publish(self):
self.published_date = timezone.now()
self.save()
def __unicode__(self):
return self.title
And from views.py my view
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('blog.views.post_detail', pk=post.pk)
else:
form = PostForm()
return render(request, 'blog/post_edit.html', {'form': form})
When you save a form using commit=False you should call the save_m2m() method of the form:
post = form.save(commit=False)
post.author = request.user
post.save()
form.save_m2m()
Another, more elegant, solution is to pass the instance with preset field to the form's constructor. Is this case you don't need to use the commit=False argument:
form = PostForm(request.POST, instance=Post(author=request.user))
if form.is_valid():
post = form.save()
return redirect('blog.views.post_detail', pk=post.pk)

Categories

Resources