Django:防止表单被保存在models.py中

时间:2018-04-15 21:14:20

标签: python django

我正在使用Django应用程序,用户可以在其中提出问题,但问题是,如果用户在问题表格中输入???%%等,提交它,然后slug变为''slug == '')&表单将保存到数据库中。

class Question(models.Model):
    question_text = models.CharField(max_length=250)
    slug = models.SlugField(max_length=255, unique=True)

    def get_unique_slug(self):
        slug = slugify(self.question_text)
        unique_slug = slug
        num = 1
        while Question.objects.filter(slug=unique_slug).exists():
            unique_slug = '{}-{}'.format(slug, num)
            num += 1
        if slug == '':

            # what can we do now?

        return unique_slug

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = self.get_unique_slug()
        return super(Question, self).save()

我们必须要么阻止slug成为空字符串,要么只是阻止表单被保存。我们怎么能这样做?

谢谢!

2 个答案:

答案 0 :(得分:1)

您可以将get_unique_slug移动到模型的clean方法中。这样就可以在保存实例之前验证slug。

def clean():
    if not self.slug:
        self.slug = self.get_unique_slug()
    if self.slug == '':
        raise forms.ValidationError("Invalid slug")

答案 1 :(得分:0)

如果您想保存某些内容而不是空字符串, 这样就可以了。

from django.template.defaultfilters import slugify
import random
import string

def get_unique_slug(instance,new_slug=None,field="question_text"):
    ''' If you want to target another field, you can change the parameter.
    By default we target the "question_text" field '''

    def generator(size=10,chars=string.ascii_letters + string.digits):
        return ''.join(random.choice(chars) for _ in range(size))
    if new_slug:
        slug = new_slug
    else:
        slug = slugify(eval("instance.%s" % field))  # we use `eval` to have the field. 
        if not slug:
            slug = "question{}".format(generator(4))

    Klass = instance.__class__
    qs_exists = Klass.objects.filter(slug=slug).exists()

    if qs_exists:
        new_slug = "%s-%s" % (slug,generator(4))
        return create_slug(instance,new_slug,field)
    return slug

这是你的班级模特。 我没有在课程中加入'get_unique_slug',以便您可以在任何地方使用其他模型

class Question(models.Model):
    question_text = models.CharField(max_length=250)
    slug = models.SlugField(max_length=255, unique=True)

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = get_unique_slug(self,field="question_text") # We target the 'question_text' field, although we can let it empty as it's the default value
        return super(Question, self).save()