[英]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).我在 Reddit 上看到了这个问题( https://www.reddit.com/r/django/comments/chalnz/how_can_i_prevent_my_site_users_from_publishing/ )但是在 Reddit 上分享代码很快就会变得一团糟,所以决定在这里分享答案(看看我下面的评论)。
Note - To try and keep Stack Overflow professional, I have used asterisks to cover up some of the swear words.注意 - 为了保持 Stack Overflow 的专业性,我使用星号来掩盖一些脏话。 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.
对于普通文本(但不是代码),Stack Overflow 使用星号表示需要粗体或斜体格式的文本,因此我在整个帖子中使用星号是不一致的。
forms.py 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模型.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视图.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. Chepner 正确地指出了我最初的方法中的一个缺陷,即完全合法的单词,如 Scunthorpe(英格兰的一个地方)不会被接受,因为它们包含令人反感的子字符串。 In Scunthorpes case look at the 2nd to 5th letter.
在斯肯索普斯的案例中,请查看第 2 到第 5 个字母。 You can read more about this problem here https://en.wikipedia.org/wiki/Scunthorpe_problem .
您可以在此处阅读有关此问题的更多信息https://en.wikipedia.org/wiki/Scunthorpe_problem 。
You can avoid this issue to a certain extent with more elaborate if statements.您可以通过更详细的 if 语句在一定程度上避免此问题。
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.
如果原始帖子是关于厕所的,那么您的网站读者可能会合理地希望在评论部分使用 *hit 这个词。 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).
如果你要全面禁止 *hit 这个词,你还必须过滤掉故意的拼写错误,比如 s*1t(用 i 代替 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:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.