如何告诉django不要在数据库中保存实例?

时间:2014-02-12 21:11:05

标签: django django-signals

我已经在django 1.6中编写了这个信号接收器,用于阻止包含被保存数据库中的坏词的发布评论:

@receiver(pre_save, sender= Comment)
def spam_filter(sender, **kwargs):
    cmnt = kwargs['instance']
    my_expression = '|'.join(re.escape(word) for word in BAD_WORDS)

    if re.search(my_expression, cmnt.body, flags=re.IGNORECASE):    
        #pervent the comment from being saved


    else:
        pass

我想知道如何告诉django代替'#pervent comment being saved'而不保存'bad'评论实例?

P.S。视角:

@login_required
def add_comment(request, post_id):  

    p= Blog.objects.get(id=post_id)
    post_slug = p.slug
    cform = CommentForm(request.POST)
    if cform.is_valid():
        c = cform.save(commit = False)
        c.created = timezone.now()
        c.post = p
        c.author = request.user
        c.save()
        args=post_slug
        messages.info(request, "comment was added")  
        return HttpResponseRedirect(reverse("Blog.views.post_withslug", 
                                            args=[post_slug]))

2 个答案:

答案 0 :(得分:4)

根据您对Django的新见解,我将提供替代解决方案。尝试在表单验证期间查找坏词。您可以按照以下格式writing a method for a specific field检查特定表单字段:def clean_<fieldname>。如果您的CommentForm的字段名称为body,我们可以执行以下操作:

from django import forms

class CommentForm(forms.Form):
    # Everything as before.
    ...

    def clean_body(self):
        body = self.cleaned_data['body']
        my_expression = '|'.join(re.escape(word) for word in BAD_WORDS)

        if re.search(my_expression, body, flags=re.IGNORECASE):    
            # prevent the comment from being saved
            raise forms.ValidationError("Wash your mouth out with soap.")

        # Always return the cleaned data, whether you have changed it or
        # not.
        return body

编辑:

看到你的观点后会有一些额外的评论。

您应该能够将上述def clean_body()功能添加到CommentForm并使其按预期运行。您发布的观看次数仅在form.is_valid()评估为True时才会回复。如果某人的评论包含错误字词并且form.is_valid评估为False,则需要确保该视图可以处理。请参阅示例代码here for a typical Django function based view。如果在修复这些内容之后,您仍然遇到问题,请发布CommentForm和模板代码以及任何例外情况。请务必删除原始信号代码。

p = Blog.objects.get(id=post_id)替换为p = get_object_or_404(Blog, pk=post_id)。这样,如果用户提供了错误的post_id,他们将立即获得404而不是抛出异常,因为get()将无法找到单个对象。 get_object_or_404 here上的文档。

您还可以在创建模型automatically add the current time时保存几行:

class Comment(models.Model):
    created = models.DateField(auto_add_now=True)

然后您可以从视图中删除c.created = timezone.now()

答案 1 :(得分:1)

我认为你可以提出一些例外并抓住

try:
    MyModel.objects.save() #or create
except ValidationError:
    do_other_staff
你的代码中的

if not re.search(my_expression, cmnt.body, flags=re.IGNORECASE): 
    return True

raise ValidationError('this text explains an error')