Raise error when slug already exists
The good

So, you're trying to allow users to create new questions, but those questions must have a slug which is unique. You're enforcing this on the database level with unique=True, which is a good start.

You are using a form to handle the creation of new questions, which is definitely the right way to do this. It'll also be really useful when you need to build in the ability to edit a question, since you can just reuse the same form.

The bad

But you're enforcing the uniqueness of a question outside of the form. The form ultimately has the business logic that determines whether or not the input is valid, which is why Django has built-in support for validating forms. If you find issue with isolating your form validation logic inside of a form, I would recommend breaking it out as general utilities which can be easily tested.

Right now you're enforcing these constraints either on the model level (through save, which is definitely not the right place) or on the view level (through form_valid, which is not right but also not horrible).

Django designed the generic views to be easy to implement, assuming you follow the standard Django conventions. If you don't follow the conventions, you end up with cases like your form_valid where you have to do additional validation and then decide that it's actually invalid, forcing them to form_invalid. You shouldn't have made it to form_valid, since the state is not actually valid.

The fix

You should move your uniqueness logic into the form. Since you are only validating a single field, the title field, you only need to handle the logic for that field. This means that you can isolate your logic inside a custom cleaning method.

class QuestionForm(ModelForm):

    class Meta:
         model = Question
         fields = ['title', 'text']

    def clean_title(self, title):
        from django.utils.text import slugify
        from django.core.exceptions import ValidationError

        slug = slugify(title)

        if Question.objects.filter(slug=slug).exists():
            raise ValidationError('A question with this title already exists.')

        return title

class QuestionCreate(generic.CreateView):
    form_class = QuestionForm


This means that you no longer need the form_valid override and you don't need to worry about having to replicate that validation logic in other places which use this form.