I saw this question asked on Reddit ( https://www.reddit.com/r/django/comments/chalnz/how_can_i_prevent_my_site_users_from_publishing/ ) but sharing code on Reddit quickly gets messy so decided to share the answer here (look at my comment below).
Note - To try and keep Stack Overflow professional, I have used asterisks to cover up some of the swear words. For normal text (but not code) Stack Overflow uses asterisks to indicate text that needs bold or italic formatting, so my use of asterisks throughout the post is inconsistent.
forms.py
from blog.models import Comment
from django import forms
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ('email', 'body')
def clean_body(self):
body = self.cleaned_data.get("body")
if "f**k" in body or "s**t" in body :
raise forms.ValidationError("No swearing.")
return body
def clean_email(self):
email = self.cleaned_data.get("email")
if not "gmail.com" in email:
raise forms.ValidationError("Email has to be gmail.com")
return email
models.py
class Comment(models.Model):
#The foriegn key is linked to the ID field in the Post model
#id = models.IntegerField(primary_key=True, blank=False)
post = models.ForeignKey(Post,on_delete=models.CASCADE,related_name='comments')
nameid = models.ForeignKey(User,on_delete=models.CASCADE,related_name='commentsid')
name = models.CharField(max_length=80)
email = models.EmailField()
body = models.TextField()
created_on= models.DateTimeField(default = timezone.now())
active = models.BooleanField(default=True)
views.py
def post_detail(request, pk_slug):
template_name = 'post_detail.html'
if pk_slug.isdigit():
post = Post.objects.filter(id=pk_slug).first()
else:
post = Post.objects.filter(url=pk_slug).first()
comments = Comment.objects.filter(post=post.id ,active=True)
new_comment = None
if request.method == 'POST':
comment_form = CommentForm(data=request.POST)
if comment_form.is_valid():
# Post instance which will be assigned to post attribute in Comment model
new_comment = comment_form.save(commit=False)
new_comment.post = get_object_or_404(Post, id=post.id)
new_comment.name = request.user.username
new_comment.nameid = request.user
new_comment.save()
comment_form=CommentForm()
else:
comment_form = CommentForm()
return render(request, template_name, {'post': post,
'comments': comments,
'new_comment': new_comment,
'comment_form': comment_form})
Update
Chepner rightly pointed out a flaw in my original approach whereby perfectly legitimate words such as Scunthorpe (a place in England) would not be accepted because they contain offensive sub strings. In Scunthorpes case look at the 2nd to 5th letter. You can read more about this problem here https://en.wikipedia.org/wiki/Scunthorpe_problem .
You can avoid this issue to a certain extent with more elaborate if statements.
def clean_body(self):
body = self.cleaned_data.get("body")
if not "Scunthorpe" in body:
if "c**t" in body:
raise forms.ValidationError("No swearing.")
return body
Another problem with this approach is it does not take into consideration the topics brought up in the original post. If the original post was about toilets then your sites readers may legitimately want to use the word *hit in the comment section. And if you were going to have a blanket ban on the word *hit, you would also have to filter out deliberate misspellings like s*1t (substituting the i for a 1).
A potential compromise is making it so any comment that potentially contains offensive language is manually read by a super user before the comment is published on the site.
def post_detail(request, pk_slug):
template_name = 'post_detail.html'
if pk_slug.isdigit():
post = Post.objects.filter(id=pk_slug).first()
else:
post = Post.objects.filter(url=pk_slug).first()
comments = Comment.objects.filter(post=post.id ,active=True)
#post = Post.objects.get(pk=pk)
new_comment = None
if request.method == 'POST':
comment_form = CommentForm(data=request.POST)
if comment_form.is_valid():
#print(comment_form.cleaned_data)
# Post instance which will be assigned to post attribute in Comment model
#post_instance = get_object_or_404(Post, id=post.id)
new_comment = comment_form.save(commit=False)
new_comment.post = get_object_or_404(Post, id=post.id)
if "f**k" in new_comment.body or "s**t" in new_comment.body or "s*1t" in new_comment.body :
new_comment.active = False
new_comment.name = request.user.username
new_comment.nameid = request.user
new_comment.save()
print(comment_form)
comment_form=CommentForm()
else:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.