def clean(self):
        super(WebHookTargetForm, self).clean()

        custom_content = self.cleaned_data.get('custom_content', '')
        self.cleaned_data['use_custom_content'] = len(custom_content) > 0

        apply_to = self.cleaned_data.get('apply_to')

        if (apply_to != WebHookTarget.APPLY_TO_SELECTED_REPOS or
            'repositories' not in self.cleaned_data):
            self.cleaned_data['repositories'] = Repository.objects.none()
        else:
            queryset = self.cleaned_data['repositories']
            local_site = self.cleaned_data.get('local_site')
            errors = []

            for repository in queryset:
                if repository.local_site != local_site:
                    errors.append(
                        _('Repository with ID %(id)s is invalid.')
                        % {'id': repository.pk})

            if errors:
                del self.cleaned_data['repositories']
                self._errors['repositories'] = self.error_class(errors)

        return self.cleaned_data
Validate the state of the entire form.
dataset/ETHPy150Open reviewboard/reviewboard/reviewboard/notifications/forms.py/WebHookTargetForm.clean