简体   繁体   中英

How can I prevent my site users from publishing posts that contain swear words?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM