python - 如何防止我的网站用户发布包含脏话的帖子?
问题描述
我在 Reddit 上看到了这个问题(https://www.reddit.com/r/django/comments/chalnz/how_can_i_prevent_my_site_users_from_publishing/)但是在 Reddit 上共享代码很快就会变得混乱,所以决定在这里分享答案(看看我下面的评论)。
解决方案
注意 - 为了保持 Stack Overflow 的专业性,我使用星号来掩盖一些脏话。对于普通文本(但不是代码),Stack Overflow 使用星号表示需要粗体或斜体格式的文本,因此我在整个帖子中使用星号是不一致的。
表格.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
模型.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)
视图.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})
更新
Chepner 正确地指出了我最初方法中的一个缺陷,即完全合法的单词,例如 Scunthorpe(英格兰的一个地方)不会被接受,因为它们包含令人反感的子字符串。在斯肯索普斯的案例中,请查看第 2 到第 5 个字母。您可以在此处阅读有关此问题的更多信息https://en.wikipedia.org/wiki/Scunthorpe_problem。
您可以通过更详细的 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
这种方法的另一个问题是它没有考虑原始帖子中提出的主题。如果原始帖子是关于厕所的,那么您的网站读者可能会合理地希望在评论部分使用 *hit 这个词。如果你要全面禁止 *hit 这个词,你还必须过滤掉像 s*1t 这样的故意拼写错误(用 i 代替 1)。
一个潜在的妥协是让超级用户在评论发布到网站之前手动阅读任何可能包含冒犯性语言的评论。
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:
推荐阅读
- php - Nova actionable_id 不能为空
- wpf - 复杂的 WPF 组合框
- testing - 评估软件架构/测试软件属性(如“可扩展性”)的最佳方法,无需具体说明?
- c++ - qInstallMessageHandler 不接受公共方法作为参数
- html - 如何增加变换:悬停时缩放半径
- python - BalancedBatchGenerator 抛出 AttributeError model.fit_generator
- python-3.x - 为什么即使在 python-3 电子邮件解析中解码后我也会得到一个字节字符串?
- javascript - 用 classList remove 删除一个类
- regex - 有没有办法在正则表达式中的字符集之间进行选择?
- java - 使用@PreAuthorize 时,Spring SpelExpression 似乎没有读取我的 bean