class RecipesAdmin(admin.ModelAdmin): formfield_overrides = { models.ManyToManyField: {'widget': FilteredSelectMultiple( "Ingredient", False)}, } inlines = (IngredientQuantityInline,)
class ContatoForm(ModelForm): class Meta: model = Contato fields = [ 'nome', 'nome_social', 'apelido', 'data_nascimento', 'estado_civil', 'sexo', 'identidade_genero', 'nivel_instrucao', 'naturalidade', 'tem_filhos', 'quantos_filhos', 'profissao', 'pronome_tratamento', 'tipo_autoridade', 'nome_pai', 'nome_mae', 'numero_sus', 'cpf', 'titulo_eleitor', 'rg', 'rg_orgao_expedidor', 'rg_data_expedicao', 'ativo', 'observacoes', 'cargo', 'grupodecontatos_set' ] grupodecontatos_set = ModelMultipleChoiceField( queryset=GrupoDeContatos.objects.all(), required=False, label='', widget=FilteredSelectMultiple('grupodecontatos_set', False), ) def __init__(self, *args, **kwargs): instance = None super(ContatoForm, self).__init__(*args, **kwargs) if isinstance(self.instance, Contato): instance = self.instance if 'tipo_autoridade' in self.fields: self.fields['tipo_autoridade'].widget.attrs.update( {'onchange': 'atualizaPronomes(event)'}) self.fields['pronome_tratamento'].widget = forms.RadioSelect() self.fields['pronome_tratamento'].queryset = \ PronomeTratamento.objects.order_by( 'prefixo_nome_singular_m', 'nome_por_extenso') if 'tipo_autoridade' in self.fields and\ instance and instance.tipo_autoridade: pronomes_choice = instance.tipo_autoridade.pronomes.order_by( 'prefixo_nome_singular_m', 'nome_por_extenso') else: pronomes_choice = self.fields['pronome_tratamento'].queryset self.fields['pronome_tratamento'].choices = [ (p.pk, '%s, %s - %s - %s - %s - %s - %s - %s' % (p.prefixo_nome_singular_m, p.prefixo_nome_singular_f, p.nome_por_extenso, p.abreviatura_singular_m, p.abreviatura_plural_m, p.vocativo_direto_singular_m, p.vocativo_indireto_singular_m, p.enderecamento_singular_m)) for p in pronomes_choice ] self.fields[ 'grupodecontatos_set'].widget = forms.CheckboxSelectMultiple() self.fields['grupodecontatos_set'].inline_class = True self.fields['grupodecontatos_set'].queryset = \ GrupoDeContatos.objects.filter(workspace=self.initial['workspace']) if self.instance and self.instance.pk: self.fields['grupodecontatos_set'].initial = list( self.instance.grupodecontatos_set.all()) def clean(self): pronome = self.cleaned_data['pronome_tratamento'] if 'tipo_autoridade' in self.cleaned_data: tipo_autoridade = self.cleaned_data['tipo_autoridade'] if tipo_autoridade and not pronome: self._errors['pronome_tratamento'] = [ _('Tendo sido selecionado um tipo de autoridade, \ o campo pronome de tratamento se torna obrigatório.') ]
def __init__(self, *args, **kwargs): contest = kwargs.pop('contest', None) super(EditParticipant, self).__init__(*args, **kwargs) team_queryset = Team.objects.all().order_by('username') participant_queryset = User.objects.filter( category__category='Participant', role__short_name='team') self_registered_queryset = User.objects.filter( category__category='Self Registered', role__short_name='team') system_queryset = User.objects.filter(category__category='System', role__short_name='team') observer_queryset = User.objects.filter(category__category='Observer', role__short_name='team') organization_queryset = User.objects.filter( category__category='Organization', role__short_name='team') team_initial = contest.team.all() participant_initial = contest.user.all().filter( category__category='Participant') self_registered_initial = contest.user.all().filter( category__category='Self Registered') observer_initial = contest.user.all().filter( category__category='Observer') system_initial = contest.user.all().filter(category__category='System') organization_initial = contest.user.all().filter( category__category='Organization') self.fields['team'] = forms.ModelMultipleChoiceField( queryset=team_queryset, widget=FilteredSelectMultiple(('tags'), is_stacked=False), required=False, initial=team_initial, ) self.fields['participant'] = forms.ModelMultipleChoiceField( queryset=participant_queryset, widget=FilteredSelectMultiple(('tags'), is_stacked=False), required=False, initial=participant_initial, ) if self_registered_queryset: self.fields['self_registered'] = forms.ModelMultipleChoiceField( queryset=self_registered_queryset, widget=FilteredSelectMultiple(('tags'), is_stacked=False), required=False, initial=self_registered_initial, ) if observer_queryset: self.fields['observer'] = forms.ModelMultipleChoiceField( queryset=observer_queryset, widget=FilteredSelectMultiple(('tags'), is_stacked=False), required=False, initial=observer_initial, ) if system_queryset: self.fields['system'] = forms.ModelMultipleChoiceField( queryset=system_queryset, widget=FilteredSelectMultiple(('tags'), is_stacked=False), required=False, initial=system_initial, ) if organization_queryset: self.fields['organization'] = forms.ModelMultipleChoiceField( queryset=organization_queryset, widget=FilteredSelectMultiple(('tags'), is_stacked=False), required=False, initial=organization_initial, )
class CarouselForm(forms.Form): """ A form that modifies carousel settings for a journal. """ carousel_mode = forms.ChoiceField( choices=models.Carousel.get_carousel_modes(), required=False, ) carousel_article_limit = forms.IntegerField( required=True, label='Maximum number of articles to show', ) carousel_news_limit = forms.IntegerField( required=True, label='Maximum number of news items to show', ) carousel_exclude = forms.BooleanField( required=False, label='Exclude selected articles', ) carousel_articles = forms.ModelMultipleChoiceField( queryset=submission_models.Article.objects.none(), required=False, widget=FilteredSelectMultiple("Article", False, attrs={'rows': '2'}) ) carousel_news = forms.ModelMultipleChoiceField( queryset=comms_models.NewsItem.objects.none(), required=False, widget=FilteredSelectMultiple( "News Article", False, attrs={'rows': '2'}, ) ) def __init__(self, *args, **kwargs): request = kwargs.pop('request', None) article_list, news_list = self.load(request) super(CarouselForm, self).__init__(*args, **kwargs) if request.site_type and request.site_type.carousel is not None: self.initial['carousel_mode'] = request.site_type.carousel.mode self.initial['carousel_exclude'] = request.site_type.carousel.exclude self.initial['carousel_articles'] = article_list self.initial['carousel_article_limit'] = request.site_type.carousel.article_limit self.initial['carousel_news_limit'] = request.site_type.carousel.news_limit self.initial['carousel_news'] = news_list published_articles = submission_models.Article.objects.filter( stage=submission_models.STAGE_PUBLISHED, date_published__lte=timezone.now() ) if request.journal: published_articles = published_articles.filter( journal=request.journal ) self.fields['carousel_articles'].queryset = published_articles news_items = comms_models.NewsItem.objects.filter( content_type=request.model_content_type, object_id=request.site_type.pk, ) self.fields['carousel_news'].queryset = news_items def load(self, request): # if no carousel set, create one if request.site_type and request.site_type.carousel is None: return [], submission_models.Article.objects.none() articles = request.site_type.carousel.articles.all() article_list = [] news_list = [] for article in articles: article_list.append(article.pk) for item in request.site_type.carousel.news_articles.all(): news_list.append(item.pk) return article_list, news_list def save(self, request, commit=True): mode = self.cleaned_data["carousel_mode"] exclude = self.cleaned_data["carousel_exclude"] article_limit = self.cleaned_data["carousel_article_limit"] news_limit = self.cleaned_data["carousel_news_limit"] list_of_articles = self.cleaned_data["carousel_articles"] list_of_news = self.cleaned_data["carousel_news"] if request.site_type.carousel is None: carousel = models.Carousel.objects.create() request.site_type.carousel = carousel request.site_type.carousel.save() request.site_type.save() request.site_type.carousel.mode = mode request.site_type.carousel.article_limit = article_limit request.site_type.carousel.news_limit = news_limit if mode == "selected" or mode == "mixed-selected": # you can't use the same list of articles to include and exclude exclude = False request.site_type.carousel.exclude = exclude request.site_type.carousel.articles.clear() request.site_type.carousel.news_articles.clear() for article in list_of_articles: request.site_type.carousel.articles.add(article) for news in list_of_news: request.site_type.carousel.news_articles.add(news) if commit: request.site_type.carousel.save() request.site_type.save() messages.add_message( request, messages.SUCCESS, 'Journal carousel settings saved', ) def clean(self): cleaned_data = self.cleaned_data return cleaned_data
class NetworkEditForm(forms.ModelForm): repeaters = forms.ModelMultipleChoiceField(queryset=models.Repeater.objects.all().order_by("district__name","site_name"),widget=FilteredSelectMultiple(verbose_name='Repeater',is_stacked=False),required=False) def __init__(self,*args,**kwargs): super().__init__(*args,**kwargs) if self.instance and self.instance.pk: self.initial["repeaters"] = models.Repeater.objects.filter(network=self.instance) if "name" in self.fields : self.fields["name"].widget = text_readonly_widget def save(self,*args,**kwargs): obj = super().save(*args,**kwargs) if kwargs["commit"]: self.save_repeaters() return obj def save_repeaters(self): repeaters = self.cleaned_data["repeaters"] repeater_ids = [obj.id for obj in repeaters] if repeaters else [] for repeater in models.Repeater.objects.filter(network=self.instance).exclude(id__in=repeater_ids): repeater.network = None repeater.save(update_fields=["network"]) for repeater in models.Repeater.objects.filter(id__in=repeater_ids).exclude(network=self.instance): repeater.network = self.instance repeater.save(update_fields=["network"]) class Meta: model = models.Network fields = "__all__" widgets = { }
def __init__(self, *args, **kwargs): super(GroupForm, self).__init__(*args, **kwargs) self.fields['permissions'] = forms.MultipleChoiceField(required=False, widget=FilteredSelectMultiple(ugettext('Permissions'), False)) permissions_objs = Permission.objects.all().order_by('name') choices = [] for perm_obj in permissions_objs: choices.append([perm_obj.id, perm_obj.name]) self.fields['permissions'].choices = choices try: current_perm_list = GroupPermissionList.objects.get( group=kwargs['instance']) self.fields['permissions'].initial = current_perm_list.permission_fk_list except (GroupPermissionList.DoesNotExist, KeyError): self.fields['permissions'].initial = []
class FormFilter(forms.ModelForm): conn_state = forms.MultipleChoiceField( required=False, widget=forms.CheckboxSelectMultiple(), choices=Filter.CONNECTION) source = forms.ModelMultipleChoiceField(Address.objects.all(), required=False, widget=FilteredSelectMultiple( 'Source', False, attrs={})) destiny = forms.ModelMultipleChoiceField(Address.objects.all(), required=False, widget=FilteredSelectMultiple( 'Destiny', False, attrs={})) srcport = forms.ModelMultipleChoiceField(Port.objects.all(), required=False, widget=FilteredSelectMultiple( 'Source Port', False, attrs={})) dstport = forms.ModelMultipleChoiceField(Port.objects.all(), required=False, widget=FilteredSelectMultiple( 'Destiny Port', False, attrs={})) week_days = forms.MultipleChoiceField( required=False, widget=forms.CheckboxSelectMultiple(), choices=Filter.WEEKDAYS) date_start = forms.DateField(widget=DateTimeInput( format='%Y-%m-%d', attrs={'class': 'datepicker'}), required=False) date_stop = forms.DateField(widget=DateTimeInput( format='%Y-%m-%d', attrs={'class': 'datepicker'}), required=False) time_start = forms.TimeField(widget=DateTimeInput( format='%H:%M', attrs={'class': 'timepicker'}), required=False) time_stop = forms.TimeField(widget=DateTimeInput( format='%H:%M', attrs={'class': 'timepicker'}), required=False) def clean(self): cleaned_data = super(FormFilter, self).clean() if not (bool(self.cleaned_data['srcset']) != bool( self.cleaned_data['source'])): raise forms.ValidationError, 'Fill in only one of the two source fields' if not (bool(self.cleaned_data['dstset']) != bool( self.cleaned_data['destiny'])): raise forms.ValidationError, 'Fill in only one of the two destiny fields' if (bool(self.cleaned_data['protocol']) != bool( bool(self.cleaned_data['dstport']) or bool(self.cleaned_data['srcport']))): raise forms.ValidationError, 'You need set protocol TCP or UDP using destination and/or source ports' if (self.cleaned_data['chain'].name == 'INPUT' and bool(self.cleaned_data['out_interface'])): raise forms.ValidationError, 'You cant use output interface when using the chain INPUT' if (self.cleaned_data['chain'].name == 'OUTPUT' and bool(self.cleaned_data['in_interface'])): raise forms.ValidationError, 'You cant use input interface when using the chain OUTPUT' return cleaned_data class Meta: model = Filter
class ProductExportForm(ExportForm): export_fields = ModelFieldListFormField(source_model=Product, label='Поля для экспорта', widget=FilteredSelectMultiple('свойства товара', False))
class Meta: widgets = { 'comparison': FilteredSelectMultiple('свойства товара', False) }
class AppUserEditForm(forms.ModelForm): tools_access_role_arn = forms.CharField( label="Tools access IAM role arn", help_text="The arn for the IAM role required to start local tools", required=False, widget=AdminTextInputWidget(), ) home_directory_efs_access_point_id = forms.CharField( label="Home directory ID", help_text="EFS Access Point ID", max_length=128, required=False, empty_value=None, widget=AdminTextInputWidget(), ) can_start_all_applications = forms.BooleanField( label="Can start local tools", help_text="For JupyterLab, rStudio and pgAdmin", required=False, ) can_develop_visualisations = forms.BooleanField( label="Can develop visualisations", help_text="To deploy and manage visualisations from code in Gitlab", required=False, ) can_access_appstream = forms.BooleanField(label="Can access AppStream", help_text="For SPSS and STATA", required=False) can_access_quicksight = forms.BooleanField( label="Can access QuickSight", help_text= "Note: the user must also be given separate access to AWS QuickSight via DIT SSO", required=False, ) authorized_master_datasets = forms.ModelMultipleChoiceField( required=False, widget=FilteredSelectMultiple("master datasets", False), queryset=MasterDataset.objects.live().filter( user_access_type=UserAccessType.REQUIRES_AUTHORIZATION).order_by( "name"), ) authorized_data_cut_datasets = forms.ModelMultipleChoiceField( required=False, widget=FilteredSelectMultiple("data cut datasets", False), queryset=DataCutDataset.objects.live().filter( user_access_type=UserAccessType.REQUIRES_AUTHORIZATION).order_by( "name"), ) authorized_visualisations = forms.ModelMultipleChoiceField( label="Authorized visualisations", required=False, widget=FilteredSelectMultiple("visualisations", False), queryset=None, ) class Meta: model = get_user_model() fields = "__all__" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) instance = kwargs["instance"] self.fields[ "tools_access_role_arn"].initial = instance.profile.tools_access_role_arn self.fields["tools_access_role_arn"].widget.attrs[ "class"] = "vTextField" self.fields[ "home_directory_efs_access_point_id"].initial = instance.profile.home_directory_efs_access_point_id self.fields["home_directory_efs_access_point_id"].widget.attrs[ "class"] = "vTextField" self.fields[ "can_start_all_applications"].initial = instance.user_permissions.filter( codename="start_all_applications", content_type=ContentType.objects.get_for_model( ApplicationInstance), ).exists() self.fields[ "can_develop_visualisations"].initial = instance.user_permissions.filter( codename="develop_visualisations", content_type=ContentType.objects.get_for_model( ApplicationInstance), ).exists() self.fields[ "can_access_appstream"].initial = instance.user_permissions.filter( codename="access_appstream", content_type=ContentType.objects.get_for_model( ApplicationInstance), ).exists() self.fields[ "can_access_quicksight"].initial = instance.user_permissions.filter( codename="access_quicksight", content_type=ContentType.objects.get_for_model( ApplicationInstance), ).exists() self.fields[ "authorized_master_datasets"].initial = MasterDataset.objects.live( ).filter(datasetuserpermission__user=instance) self.fields[ "authorized_data_cut_datasets"].initial = DataCutDataset.objects.live( ).filter(datasetuserpermission__user=instance) self.fields[ "authorized_visualisations"].initial = VisualisationCatalogueItem.objects.live( ).filter(visualisationuserpermission__user=instance) self.fields[ "authorized_visualisations"].queryset = VisualisationCatalogueItem.objects.live( ).order_by("name", "id")
class ContainerSwitchForm(forms.ModelForm): sample_selection = forms.ModelMultipleChoiceField( queryset=Container.objects.all(), widget=FilteredSelectMultiple("sample_selection", is_stacked=False), required=False)
class ToolAdminForm(forms.ModelForm): class Meta: model = Tool fields = "__all__" class Media: js = ("admin/tool/tool.js", ) css = {"": ("admin/tool/tool.css", )} qualified_users = forms.ModelMultipleChoiceField( queryset=User.objects.all(), required=False, widget=FilteredSelectMultiple(verbose_name="Users", is_stacked=False), ) _backup_owners = forms.ModelMultipleChoiceField( queryset=User.objects.all(), required=False, widget=FilteredSelectMultiple(verbose_name="Users", is_stacked=False), ) required_resources = forms.ModelMultipleChoiceField( queryset=Resource.objects.all(), required=False, widget=FilteredSelectMultiple(verbose_name="Required resources", is_stacked=False), ) nonrequired_resources = forms.ModelMultipleChoiceField( queryset=Resource.objects.all(), required=False, widget=FilteredSelectMultiple(verbose_name="Nonrequired resources", is_stacked=False), ) def __init__(self, *args, **kwargs): super(ToolAdminForm, self).__init__(*args, **kwargs) if self.instance.pk: self.fields[ "qualified_users"].initial = self.instance.user_set.all() self.fields[ "required_resources"].initial = self.instance.required_resource_set.all( ) self.fields[ "nonrequired_resources"].initial = self.instance.nonrequired_resource_set.all( ) def clean(self): cleaned_data = super().clean() parent_tool = cleaned_data.get("parent_tool") category = cleaned_data.get("_category") location = cleaned_data.get("_location") phone_number = cleaned_data.get("_phone_number") primary_owner = cleaned_data.get("_primary_owner") image = cleaned_data.get("_image") # only resize if an image is present and has changed if image and not isinstance(image, FieldFile): from NEMO.utilities import resize_image # resize image to 500x500 maximum cleaned_data["_image"] = resize_image(image, 500) if parent_tool: if parent_tool.id == self.instance.id: self.add_error( "parent_tool", "You cannot select the parent to be the tool itself.") # in case of alternate tool, remove everything except parent_tool and name data = dict([(k, v) for k, v in self.cleaned_data.items() if k == "parent_tool" or k == "name"]) # an alternate tool is never visible data["visible"] = False return data else: if not category: self.add_error("_category", "This field is required.") if not location: self.add_error("_location", "This field is required.") if not phone_number: self.add_error("_phone_number", "This field is required.") if not primary_owner: self.add_error("_primary_owner", "This field is required.") post_usage_questions = cleaned_data.get("_post_usage_questions") # Validate _post_usage_questions JSON format if post_usage_questions: try: loads(post_usage_questions) except ValueError: self.add_error( "_post_usage_questions", "This field needs to be a valid JSON string") try: DynamicForm(post_usage_questions, self.instance.id).validate() except Exception: error_info = sys.exc_info() self.add_error( "_post_usage_questions", error_info[0].__name__ + ": " + str(error_info[1])) policy_off_between_times = cleaned_data.get( "_policy_off_between_times") policy_off_start_time = cleaned_data.get("_policy_off_start_time") policy_off_end_time = cleaned_data.get("_policy_off_end_time") if policy_off_between_times and (not policy_off_start_time or not policy_off_end_time): if not policy_off_start_time: self.add_error("_policy_off_start_time", "Start time must be specified") if not policy_off_end_time: self.add_error("_policy_off_end_time", "End time must be specified")
def set_access_policy(self, request, queryset): policy_model = { Album: AlbumAccessPolicy, Photo: PhotoAccessPolicy }[self.model] model_name = self.model._meta.model_name policy_model_name = policy_model._meta.model_name form_class = modelform_factory( policy_model, exclude=(model_name, ), widgets={ 'users': FilteredSelectMultiple(ugettext("Users"), False), 'groups': FilteredSelectMultiple(ugettext("Groups"), False), }) if request.POST.get('set_access_policy'): form = form_class(request.POST) if form.is_valid(): queryset = queryset.select_related('access_policy') # Check permissions has_add_perm = request.user.has_perm('gallery.add_%s' % policy_model_name) has_change_perm = request.user.has_perm('gallery.change_%s' % policy_model_name) for obj in queryset: try: obj.access_policy except policy_model.DoesNotExist: if not has_add_perm: raise PermissionDenied else: if not has_change_perm: raise PermissionDenied # Apply changes created, changed = 0, 0 for obj in queryset: try: ap = obj.access_policy changed += 1 except policy_model.DoesNotExist: ap = policy_model.objects.create(**{model_name: obj}) created += 1 form_class(request.POST, instance=ap).save() message = ugettext("Successfully created %(created)d and " "changed %(changed)d access policies.") message = message % {'created': created, 'changed': changed} self.message_user(request, message) return HttpResponseRedirect( reverse('admin:gallery_%s_changelist' % model_name)) else: form = form_class() context = { 'action_checkbox_name': ACTION_CHECKBOX_NAME, 'opts': self.model._meta, 'form': form, 'media': self.media + form.media, 'photos': Photo.objects.filter(album__in=queryset), 'queryset': queryset, 'title': ugettext("Set access policy"), } return render(request, 'admin/gallery/set_access_policy.html', context)
def MembershipField(model, name): return forms.ModelMultipleChoiceField( queryset=model.objects.all(), required=False, widget=FilteredSelectMultiple(name, False) )
class CustomerAdminForm(ModelForm): owners = ModelMultipleChoiceField( User.objects.all().order_by('full_name'), required=False, widget=FilteredSelectMultiple(verbose_name=_('Owners'), is_stacked=False), ) support_users = ModelMultipleChoiceField( User.objects.all().order_by('full_name'), required=False, widget=FilteredSelectMultiple( verbose_name=_('Support users'), is_stacked=False ), ) def __init__(self, *args, **kwargs): super(CustomerAdminForm, self).__init__(*args, **kwargs) if self.instance and self.instance.pk: self.owners = self.instance.get_owners() self.support_users = self.instance.get_support_users() self.fields['owners'].initial = self.owners self.fields['support_users'].initial = self.support_users else: self.owners = User.objects.none() self.support_users = User.objects.none() self.fields['agreement_number'].initial = models.get_next_agreement_number() textarea_attrs = {'cols': '40', 'rows': '4'} self.fields['contact_details'].widget.attrs = textarea_attrs self.fields['access_subnets'].widget.attrs = textarea_attrs type_choices = [''] type_choices.extend(settings.WALDUR_CORE['COMPANY_TYPES']) self.fields['type'] = ChoiceField( required=False, choices=[(t, t) for t in type_choices] ) def save(self, commit=True): customer = super(CustomerAdminForm, self).save(commit=False) if not customer.pk: customer.save() self.populate_users('owners', customer, models.CustomerRole.OWNER) self.populate_users('support_users', customer, models.CustomerRole.SUPPORT) return customer def populate_users(self, field_name, customer, role): field = getattr(self, field_name) new_users = self.cleaned_data[field_name] removed_users = field.exclude(pk__in=new_users) for user in removed_users: customer.remove_user(user, role, self.request.user) added_users = new_users.exclude(pk__in=field) for user in added_users: # User role within customer must be unique. if not customer.has_user(user): customer.add_user(user, role, self.request.user) self.save_m2m() def clean(self): cleaned_data = super(CustomerAdminForm, self).clean() owners = self.cleaned_data['owners'] support_users = self.cleaned_data['support_users'] invalid_users = set(owners) & set(support_users) if invalid_users: invalid_users_list = ', '.join(map(str, invalid_users)) raise ValidationError( _( 'User role within organization must be unique. ' 'Role assignment of The following users is invalid: %s.' ) % invalid_users_list ) return cleaned_data def clean_accounting_start_date(self): accounting_start_date = self.cleaned_data['accounting_start_date'] if ( 'accounting_start_date' in self.changed_data and accounting_start_date < timezone.now() ): # If accounting_start_date < timezone.now(), we change accounting_start_date # but not raise an exception, because accounting_start_date default value is # timezone.now(), but init time of form and submit time of form are always diff. # And user will get an exception always if set default value. return timezone.now() return accounting_start_date
class TrainingUserForm(forms.ModelForm): states = forms.ModelMultipleChoiceField(queryset=State.objects.all(), widget=FilteredSelectMultiple( "States", is_stacked=False), label='States')
class ProjectAdminForm(ModelForm): admins = ModelMultipleChoiceField( User.objects.all().order_by('full_name'), required=False, widget=FilteredSelectMultiple(verbose_name=_('Admins'), is_stacked=False), ) managers = ModelMultipleChoiceField( User.objects.all().order_by('full_name'), required=False, widget=FilteredSelectMultiple(verbose_name=_('Managers'), is_stacked=False), ) support_users = ModelMultipleChoiceField( User.objects.all().order_by('full_name'), required=False, widget=FilteredSelectMultiple( verbose_name=_('Support users'), is_stacked=False ), ) def __init__(self, *args, **kwargs): super(ProjectAdminForm, self).__init__(*args, **kwargs) if self.instance and self.instance.pk: self.admins = self.instance.get_users(models.ProjectRole.ADMINISTRATOR) self.managers = self.instance.get_users(models.ProjectRole.MANAGER) self.support_users = self.instance.get_users(models.ProjectRole.SUPPORT) self.fields['admins'].initial = self.admins self.fields['managers'].initial = self.managers self.fields['support_users'].initial = self.support_users else: for field_name in ('admins', 'managers', 'support_users'): setattr(self, field_name, User.objects.none()) def clean(self): cleaned_data = super(ProjectAdminForm, self).clean() admins = self.cleaned_data['admins'] managers = self.cleaned_data['managers'] support_users = self.cleaned_data['support_users'] for xs, ys in itertools.combinations( [set(admins), set(managers), set(support_users)], 2 ): invalid_users = xs & ys if invalid_users: invalid_users_list = ', '.join(map(str, invalid_users)) raise ValidationError( _( 'User role within project must be unique. ' 'Role assignment of The following users is invalid: %s.' ) % invalid_users_list ) return cleaned_data def save(self, commit=True): project = super(ProjectAdminForm, self).save(commit=False) if not project.pk: project.save() self.populate_users('admins', project, models.ProjectRole.ADMINISTRATOR) self.populate_users('managers', project, models.ProjectRole.MANAGER) self.populate_users('support_users', project, models.ProjectRole.SUPPORT) return project def populate_users(self, field_name, project, role): field = getattr(self, field_name) new_users = self.cleaned_data[field_name] removed_users = field.exclude(pk__in=new_users) for user in removed_users: project.remove_user(user, role, self.request.user) added_users = new_users.exclude(pk__in=field) for user in added_users: # User role within project must be unique. if not project.has_user(user): project.add_user(user, role, self.request.user) self.save_m2m()
def get_form(self, request, obj=None, **kwargs): '''Adds the template area fields to the form.''' if not getattr(settings, 'PAGES_VERSIONING', False): request.shared_fields_editable = True content_cls = self.get_page_content_cls(request, obj) content_fields = [] form_attrs = {} for field in content_cls._meta.fields + content_cls._meta.many_to_many: if field.name == 'page': continue form_field = self.formfield_for_dbfield(field, request=request) # HACK: add in the initial value. No other way to pass this on. if obj: try: form_field.initial = getattr(obj.content, field.name, '') if isinstance(field, models.ManyToManyField) and not form_field.initial == '': form_field.initial = form_field.initial.all() except content_cls.DoesNotExist: # This means that we're in a reversion recovery, or # something weird has happened to the database. pass if field.name in getattr(content_cls, 'filter_horizontal', ()): form_field.widget = FilteredSelectMultiple( field.verbose_name, is_stacked=False, ) # Store the field. form_attrs[field.name] = form_field content_fields.append(field.name) ContentForm = type('{}Form'.format(self.__class__.__name__), (forms.ModelForm,), form_attrs) defaults = {'form': ContentForm} defaults.update(kwargs) content_defaults = { 'form': ContentForm, 'fields': content_fields, "formfield_callback": partial(self.formfield_for_dbfield, request=request) } class PageForm(super().get_form(request, obj, **defaults)): content_form_cls = modelform_factory(content_cls, **content_defaults) def full_clean(self): super().full_clean() content_instance = None if self.instance.content_type_id: content_instance = self.instance.content content_form = self.content_form_cls(self.data or None, instance=content_instance) self._errors.update(content_form.errors) # HACK: Need to limit parents field based on object. This should be # done in formfield_for_foreignkey, but that method does not know # about the object instance. if obj: invalid_parents = set(child.id for child in self.get_all_children(obj)) invalid_parents.add(obj.id) else: invalid_parents = frozenset() homepage = request.pages.homepage if homepage: parent_choices = [] for page in [homepage] + self.get_all_children(homepage): if page.id not in invalid_parents: parent_choices.append((page.id, ' \u203a '.join('{}'.format(breadcrumb.title) for breadcrumb in self.get_breadcrumbs(page)))) else: parent_choices = [] if not parent_choices: parent_choices = (('', '---------'),) if 'parent' in PageForm.base_fields: if obj and not (not obj._is_canonical_page or obj.owner_set.exists() or obj.version_set.exists()): PageForm.base_fields['parent'].choices = parent_choices elif not obj: PageForm.base_fields['parent'].choices = parent_choices # Return the completed form. return PageForm
class DocumentFieldForm(ModelFormWithUnchangeableFields): MAX_ESCAPED_FIELD_CODE_LEN = 50 R_FIELD_CODE = re.compile(r'^[a-z][a-z0-9_]*$') UNCHANGEABLE_FIELDS = ('code', 'long_code', 'document_type', 'type', 'hide_until_js') depends_on_fields = forms.ModelMultipleChoiceField( queryset=DocumentField.objects.all(), required=False, widget=FilteredSelectMultiple('depends_on_fields', False)) hide_until_python = forms.CharField( widget=forms.Textarea, required=False, help_text= 'Boolean expression in python syntax. Use field codes for this expression' ) hide_until_js = forms.CharField( widget=forms.Textarea, required=False, disabled=True, help_text= 'Target expression ("Hide until python" expression converted to JavaScript syntax for frontend). ' 'Allowed operators: +, -, *, /, ===, !==, ==, !=, &&, ||, >, <, >=, <=, %' ) long_code = forms.CharField( # widget=forms.Textarea, required=False, disabled=True) display_yes_no = forms.BooleanField( required=False, help_text='Display Yes if Related Info Text Found, otherwise No') classifier_init_script = forms.Field( required=False, widget=forms.Textarea, help_text=mark_safe('''Classifier initialization script. Here is how it used: <br /><br /> ''' + '<br />'.join( inspect.getsource(init_classifier_impl).replace(' ', ' '). replace('\t', ' ').split('\n')))) class Meta: model = DocumentField fields = '__all__' # exclude = ('long_code',) readonly_fields = ('created_by', 'modified_by') def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.fields['type'].required = True self.fields['order'].required = False self.fields['text_unit_type'].required = False self.fields['value_detection_strategy'].required = False self.fields['trained_after_documents_number'].required = False @classmethod def _extract_field_and_deps(cls, base_fields: List[DocumentField], fields_buffer: dict) -> dict: for field in base_fields: if field.code not in fields_buffer: fields_buffer[ field.code] = field.get_depends_on_codes() or set() cls._extract_field_and_deps(field.depends_on_fields.all(), fields_buffer) return fields_buffer def calc_formula(self, field_code, type_code, formula, fields_to_values, form_field, formula_name='formula'): try: FormulaBasedFieldDetectionStrategy.calc_formula( field_code, type_code, formula, fields_to_values) except DocumentFieldFormulaError as ex: base_error_class = type(ex.base_error).__name__ base_error_msg = str(ex.base_error) lines = list() lines.append( 'Error caught while trying to execute {0} on example values:'. format(formula_name)) for field_name in ex.field_values: lines.append('{0}={1}'.format(field_name, ex.field_values[field_name])) lines.append("{0}. {1} in {2} of field '{3}' at line {4}".format( base_error_class, base_error_msg, formula_name, ex.field_code, ex.line_number)) self.add_error(form_field, lines) except Exception: trace = traceback.format_exc() raise forms.ValidationError( 'Tried to eval {0} on example values:\n{1}\nGot error:\n{2}'. format(formula_name, str(fields_to_values), trace)) PARAM_CODE = 'code' def validate_field_code(self): field_code = self.cleaned_data.get(self.PARAM_CODE) or '' if not self.R_FIELD_CODE.match(field_code): self.add_error( 'code', '''Field codes must be lowercase, should start with a latin letter and contain only latin letters, digits, and underscores. You cannot use a field code you have already used for this document type.'''.format(field_code)) reserved_suffixes = ('_sug', '_txt', FIELD_CODE_ANNOTATION_SUFFIX) # TODO: define reserved suffixes/names in field_value_tables.py? collect/autodetect? for suffix in reserved_suffixes: if field_code.endswith(suffix): self.add_error( 'code', '''"{}" suffix is reserved. You cannot use a field code which ends with this suffix.'''. format(suffix)) UNSURE_CHOICE_VALUE = 'unsure_choice_value' UNSURE_THRESHOLDS = 'unsure_thresholds_by_value' def clean(self): field_code = self.cleaned_data.get('code') formula = self.cleaned_data.get('formula') type_code = self.cleaned_data.get('type') depends_on_fields = self.cleaned_data.get('depends_on_fields') or [] document_type = self.cleaned_data.get('document_type') depends_on_fields = list(depends_on_fields) classifier_init_script = self.cleaned_data['classifier_init_script'] stop_words = self.cleaned_data.get('stop_words') hide_until_python = self.cleaned_data['hide_until_python'] default_value = self.cleaned_data.get('default_value') unsure_choice_value = self.cleaned_data[self.UNSURE_CHOICE_VALUE] choice_values = DocumentField.parse_choice_values( self.cleaned_data['choices']) unsure_thresholds_by_value = self.cleaned_data.get( self.UNSURE_THRESHOLDS) try: field_type = FIELD_TYPE_REGISTRY[type_code] except KeyError: self.add_error('type', 'Unknown field type "{}".'.format(type_code)) if unsure_choice_value and (not choice_values or unsure_choice_value not in choice_values): self.add_error( self.UNSURE_CHOICE_VALUE, '"Unsure choice value" must be listed in the choice values.') if unsure_thresholds_by_value is not None: if not hasattr(unsure_thresholds_by_value, 'items'): self.add_error( self.UNSURE_THRESHOLDS, 'Must be a dict of choice values to float thresholds [0..1]' ) else: if not choice_values: self.add_error( self.UNSURE_THRESHOLDS, '"Unsure" thresholds are set but choice values are not.' ) if not unsure_choice_value: self.add_error( self.UNSURE_THRESHOLDS, '"Unsure" thresholds are set but ' '"unsure" choice value is not.') if choice_values and unsure_choice_value: for k, v in unsure_thresholds_by_value.items(): if k == unsure_choice_value: self.add_error( self.UNSURE_THRESHOLDS, 'Please set thresholds only for "sure" choice ' 'values and not for ' + k) elif k not in choice_values: self.add_error(self.UNSURE_THRESHOLDS, 'Value not in choice values: ' + k) if (not isinstance(v, int) and not isinstance(v, float)) or v < 0 or v > 1: self.add_error( self.UNSURE_THRESHOLDS, 'Threshold should be a float value between 0 and 1: ' + k) try: stop_words = compile_stop_words(stop_words) detect_value_with_stop_words(stop_words, 'dummy text') except Exception as err: self.add_error('stop_words', str(err)) try: init_classifier_impl(field_code, classifier_init_script) except ScriptError as err: self.add_error('classifier_init_script', str(err).split('\n')) fields_and_deps = { self.cleaned_data.get('code') or 'xxx': {f.code for f in depends_on_fields} } fields_and_deps = self._extract_field_and_deps(depends_on_fields, fields_and_deps) fields_and_deps = [(code, deps) for code, deps in fields_and_deps.items()] try: order_field_detection(fields_and_deps) except ValueError as ve: self.add_error(None, str(ve)) fields_to_values = { field.code: FIELD_TYPE_REGISTRY[field.type].example_python_value(field) for field in depends_on_fields } python_coded_field_code = self.cleaned_data.get('python_coded_field') if python_coded_field_code: python_coded_field = PYTHON_CODED_FIELDS_REGISTRY.get( python_coded_field_code) if not python_coded_field: self.add_error( 'python_coded_field', 'Unknown Python-coded field: {0}'.format( python_coded_field_code)) else: if type_code != python_coded_field.type: self.add_error( 'type', 'Python-coded field {0} is of type {1} but {2} is specified' ' as the field type'.format(python_coded_field.title, python_coded_field.type, type_code)) if formula and formula.strip() and type_code: self.calc_formula(field_code, type_code, formula, fields_to_values, 'formula') hide_until_python = hide_until_python.strip( ) if hide_until_python else None if hide_until_python: if not document_type: self.add_error('hide_until_python', 'Document type is not defined.') else: fields_to_values = { field.code: FIELD_TYPE_REGISTRY[field.type].example_python_value(field) for field in list(document_type.fields.all()) } if field_code and field_code in fields_to_values: del fields_to_values[field_code] if type_code: fields_to_values[field_code] = FIELD_TYPE_REGISTRY[type_code] \ .example_python_value(self.instance) self.calc_formula(field_code, None, hide_until_python, fields_to_values, 'hide_until_python', formula_name='hide until python') if default_value is not None: if type_code == RelatedInfoField.code: self.add_error('default_value', 'Related info field can\'t have default value') elif field_type.extract_from_possible_value( self.instance, default_value) != default_value: self.add_error( 'default_value', 'Wrong value for type {0}. Example: {1}'.format( type_code, json.dumps( field_type.example_python_value(self.instance)))) try: DocumentField.compile_value_regexp( self.cleaned_data['value_regexp']) except Exception as exc: self.add_error('value_regexp', exc) self.validate_field_code() if self.initial and 'type' in self.changed_data: wrong_field_detector_pks = [] for field_detector in DocumentFieldDetector.objects.filter( field=self.instance): try: DetectorFieldMatcher.validate_detected_value( type_code, field_detector.detected_value) except Exception: wrong_field_detector_pks.append('#' + field_detector.pk) if wrong_field_detector_pks: self.add_error( 'type', 'Detected value is not allowed for this field type, please unset detected value ' 'for this field detectors: {0}'.format( ', '.join(wrong_field_detector_pks))) return self.cleaned_data
class CourseForm(forms.Form): course_id = forms.CharField( label=COURSE_SINGULAR + " id", max_length=20, widget=forms.TextInput(attrs={ "class": "form-control", "placeholder": "Enter course id" }), required=True, ) course_title = forms.CharField( label="Title", max_length=200, widget=forms.TextInput(attrs={ "class": "form-control", "placeholder": "Enter course title" }), required=True, ) course_short_name = forms.CharField( label=COURSE_SINGULAR + " short name", max_length=10, widget=forms.TextInput(attrs={ "class": "form-control", "placeholder": "Enter short name" }), required=False, ) course_overview = MartorFormField( label="Overview", widget=forms.Textarea(attrs={ "class": "form-control", "placeholder": "Enter course overview", }), required=False, ) course_outcome = forms.ModelMultipleChoiceField( label="Outcomes", queryset=Outcome.objects.all(), widget=FilteredSelectMultiple(verbose_name="Outcomes", is_stacked=False), required=False, ) course_objective = forms.ModelMultipleChoiceField( label="Objectives", queryset=Objective.objects.all(), widget=FilteredSelectMultiple(verbose_name="Objectives", is_stacked=False), required=False, ) course_credit = forms.IntegerField( label="Credit", max_value=1000, min_value=1, widget=forms.NumberInput(attrs={ "class": "form-control", "placeholder": "Enter course credits", }), required=True, ) lecture_contact_hours_per_week = forms.IntegerField( label="Lecture contact hours per week", max_value=1000, min_value=0, widget=forms.NumberInput( attrs={ "class": "form-control", "placeholder": "Enter lecture contact hours", }), required=True, ) tutorial_contact_hours_per_week = forms.IntegerField( label="Tutorial contact hours per week", max_value=1000, min_value=0, widget=forms.NumberInput( attrs={ "class": "form-control", "placeholder": "Enter tutorial contact hours", }), required=True, ) practical_contact_hours_per_week = forms.IntegerField( label="Practical contact hours per week", max_value=1000, min_value=0, widget=forms.NumberInput( attrs={ "class": "form-control", "placeholder": "Enter practical contact hours", }), required=True, ) course_resources = MartorFormField( label="Resources", widget=forms.Textarea(attrs={ "class": "form-control", "placeholder": "Enter course resources", }), required=False, ) course_test = MartorFormField( label="Test", widget=forms.Textarea(attrs={ "class": "form-control", "placeholder": "Enter course test" }), required=False, ) discipline = forms.ModelMultipleChoiceField( label=DISCIPLINE_PLURAL, queryset=Discipline.objects.all(), widget=FilteredSelectMultiple(verbose_name=DISCIPLINE_PLURAL, is_stacked=False), required=False, ) def __init__(self, *args, **kwargs): super(CourseForm, self).__init__(*args, **kwargs) self.helper = FormHelper() self.helper.form_method = "POST" self.helper.form_class = "form-horizontal" self.helper.label_class = "col-md-3" self.helper.field_class = "col-md-9" self.helper.layout = Layout( Div( Field("course_id"), HTML("<br>"), Field("course_title"), HTML("<br>"), Field("course_short_name"), HTML("<br>"), Field("course_overview"), HTML("<br>"), Fieldset("Add Outcomes", FormsetLayoutObject("outcomes")), HTML("<br>"), Field("course_objective"), HTML("<br>"), Field("course_credit"), HTML("<br>"), Field("lecture_contact_hours_per_week"), HTML("<br>"), Field("tutorial_contact_hours_per_week"), HTML("<br>"), Field("practical_contact_hours_per_week"), HTML("<br>"), Field("course_resources"), HTML("<br>"), Field("course_test"), HTML("<br>"), Field("discipline"), HTML("<br>"), ButtonHolder(Submit("submit", "Submit")), ))
class OrganizationAdmin(admin.ModelAdmin): formfield_overrides = { ManyToManyField: {'widget': FilteredSelectMultiple("ylläpitäjät", is_stacked=False)}, } exclude = ('published', )
class UnitForm(forms.Form): unit_name = forms.CharField( label="Name", max_length=200, widget=forms.TextInput(attrs={ "class": "form-control", "placeholder": "Enter unit name" }), required=False, ) unit_short_name = forms.CharField( label=UNIT_SINGULAR + " short name", max_length=10, widget=forms.TextInput(attrs={ "class": "form-control", "placeholder": "Enter short name" }), required=False, ) unit_overview = MartorFormField( label="Overview", widget=forms.Textarea(attrs={ "class": "form-control", "placeholder": "Enter unit overview", }), required=False, ) unit_outcome = forms.ModelMultipleChoiceField( label="Outcomes", queryset=Outcome.objects.all(), widget=FilteredSelectMultiple(verbose_name="Outcomes", is_stacked=False), required=False, ) unit_objective = forms.ModelMultipleChoiceField( label="Objectives", queryset=Objective.objects.all(), widget=FilteredSelectMultiple(verbose_name="Objectives", is_stacked=False), required=False, ) unit_body = MartorFormField( label="Body", widget=forms.Textarea(attrs={ "class": "form-control", "placeholder": "Enter unit body" }), required=False, ) unit_resources = MartorFormField( label="Resources", widget=forms.Textarea(attrs={ "class": "form-control", "placeholder": "Enter unit resources", }), required=False, ) unit_test = MartorFormField( label="Test", widget=forms.Textarea(attrs={ "class": "form-control", "placeholder": "Enter unit test" }), required=False, ) module = forms.ModelMultipleChoiceField( label=MODULE_PLURAL, queryset=Module.objects.all(), widget=FilteredSelectMultiple(verbose_name=MODULE_PLURAL, is_stacked=False), required=False, ) def __init__(self, *args, **kwargs): super(UnitForm, self).__init__(*args, **kwargs) self.helper = FormHelper() self.helper.form_method = "POST" self.helper.form_class = "form-horizontal" self.helper.label_class = "col-md-3" self.helper.field_class = "col-md-9" self.helper.layout = Layout( Div( Field("unit_name"), HTML("<br>"), Field("unit_short_name"), HTML("<br>"), Field("unit_overview"), HTML("<br>"), Fieldset("Add Outcomes", FormsetLayoutObject("outcomes")), HTML("<br>"), Field("unit_objective"), HTML("<br>"), Field("unit_body"), HTML("<br>"), Field("unit_resources"), HTML("<br>"), Field("unit_test"), HTML("<br>"), Field("module"), HTML("<br>"), ButtonHolder(Submit("submit", "Submit")), ))
class AvatarServicesForm(SiteSettingsForm): """A form for managing avatar services.""" avatars_enabled = forms.BooleanField(label=_('Enable avatars'), required=False) enabled_services = forms.MultipleChoiceField( label='Enabled avatar services', help_text=_('The avatar services which are available to be used.'), required=False, widget=FilteredSelectMultiple(_('Avatar Services'), False)) default_service = forms.ChoiceField( label=_('Default avatar service'), help_text=_('The avatar service to be used by default for users who ' 'do not have an avatar service configured. This must be ' 'one of the enabled avatar services below.'), required=False) def __init__(self, *args, **kwargs): super(AvatarServicesForm, self).__init__(*args, **kwargs) default_choices = [('none', 'None')] enable_choices = [] for service in avatar_services: default_choices.append((service.avatar_service_id, service.name)) enable_choices.append((service.avatar_service_id, service.name)) self.fields['default_service'].choices = default_choices self.fields['enabled_services'].choices = enable_choices self.fields['enabled_services'].initial = [ service.avatar_service_id for service in avatar_services.enabled_services ] default_service = avatar_services.default_service if avatar_services.default_service is not None: self.fields['default_service'].initial = \ default_service.avatar_service_id def clean_enabled_services(self): """Clean the enabled_services field. Raises: django.core.exceptions.ValidationError: Raised if an unknown service is attempted to be enabled. """ for service_id in self.cleaned_data['enabled_services']: if not avatar_services.has_service(service_id): raise ValidationError('Unknown service "%s"' % service_id) return self.cleaned_data['enabled_services'] def clean(self): """Clean the form. This will clean the form, handling any fields that need cleaned that depend on the cleaned data of other fields. Raises: django.core.exceptions.ValidationError: Raised if an unknown service or disabled service is set to be the default. """ cleaned_data = super(AvatarServicesForm, self).clean() enabled_services = set(cleaned_data['enabled_services']) service_id = cleaned_data['default_service'] if service_id == 'none': default_service = None else: if not avatar_services.has_service(service_id): raise ValidationError('Unknown service "%s".' % service_id) elif service_id not in enabled_services: raise ValidationError('Cannot set disabled service "%s" to ' 'default.' % service_id) default_service = avatar_services.get('avatar_service_id', service_id) cleaned_data['default_service'] = default_service return cleaned_data def save(self): """Save the enabled services and default service to the database.""" avatar_services.set_enabled_services([ avatar_services.get('avatar_service_id', service_id) for service_id in self.cleaned_data['enabled_services'] ], save=False) avatar_services.set_default_service( self.cleaned_data['default_service'], save=False) avatar_services.avatars_enabled = self.cleaned_data['avatars_enabled'] avatar_services.save() class Meta: title = _('Avatar Services') fieldsets = ({ 'fields': ('avatars_enabled', 'default_service', 'enabled_services'), }, )
class ToolAdminForm(forms.ModelForm): class Meta: model = Tool fields = '__all__' class Media: js = ("tool_form_admin.js",) css = {'':('tool_form_admin.css',),} qualified_users = forms.ModelMultipleChoiceField( queryset=User.objects.all(), required=False, widget=FilteredSelectMultiple( verbose_name='Users', is_stacked=False ) ) _backup_owners = forms.ModelMultipleChoiceField( queryset=User.objects.all(), required=False, widget=FilteredSelectMultiple( verbose_name='Users', is_stacked=False ) ) required_resources = forms.ModelMultipleChoiceField( queryset=Resource.objects.all(), required=False, widget=FilteredSelectMultiple( verbose_name='Required resources', is_stacked=False ) ) nonrequired_resources = forms.ModelMultipleChoiceField( queryset=Resource.objects.all(), required=False, widget=FilteredSelectMultiple( verbose_name='Nonrequired resources', is_stacked=False ) ) def __init__(self, *args, **kwargs): super(ToolAdminForm, self).__init__(*args, **kwargs) if self.instance.pk: self.fields['qualified_users'].initial = self.instance.user_set.all() self.fields['required_resources'].initial = self.instance.required_resource_set.all() self.fields['nonrequired_resources'].initial = self.instance.nonrequired_resource_set.all() def clean(self): cleaned_data = super().clean() parent_tool = cleaned_data.get("parent_tool") category = cleaned_data.get("_category") location = cleaned_data.get("_location") phone_number = cleaned_data.get("_phone_number") primary_owner = cleaned_data.get("_primary_owner") image = cleaned_data.get("_image") # only resize if an image is present and has changed if image and not isinstance(image, FieldFile): from NEMO.utilities import resize_image # resize image to 500x500 maximum cleaned_data['_image'] = resize_image(image, 500) if parent_tool: if parent_tool.id == self.instance.id: self.add_error('parent_tool', 'You cannot select the parent to be the tool itself.') # in case of alternate tool, remove everything except parent_tool and name data = dict([(k, v) for k, v in self.cleaned_data.items() if k == "parent_tool" or k == "name"]) # an alternate tool is never visible data['visible'] = False return data else: if not category: self.add_error('_category', 'This field is required.') if not location: self.add_error('_location', 'This field is required.') if not phone_number: self.add_error('_phone_number', 'This field is required.') if not primary_owner: self.add_error('_primary_owner', 'This field is required.') post_usage_questions = cleaned_data.get("_post_usage_questions") # Validate _post_usage_questions JSON format if post_usage_questions: try: loads(post_usage_questions) except ValueError as error: self.add_error("_post_usage_questions", "This field needs to be a valid JSON string") policy_off_between_times = cleaned_data.get("_policy_off_between_times") policy_off_start_time = cleaned_data.get("_policy_off_start_time") policy_off_end_time = cleaned_data.get("_policy_off_end_time") if policy_off_between_times and (not policy_off_start_time or not policy_off_end_time): if not policy_off_start_time: self.add_error("_policy_off_start_time", "Start time must be specified") if not policy_off_end_time: self.add_error("_policy_off_end_time", "End time must be specified")
class AppUserEditForm(forms.ModelForm): home_directory_efs_access_point_id = forms.CharField( label='Home directory ID', help_text='EFS Access Point ID', max_length=128, required=False, empty_value=None, widget=AdminTextInputWidget(), ) can_start_all_applications = forms.BooleanField( label='Can start local tools', help_text='For JupyterLab, rStudio and pgAdmin', required=False, ) can_develop_visualisations = forms.BooleanField( label='Can develop visualisations', help_text='To deploy and manage visualisations from code in Gitlab', required=False, ) can_access_appstream = forms.BooleanField(label='Can access AppStream', help_text='For SPSS and STATA', required=False) can_access_quicksight = forms.BooleanField( label='Can access QuickSight', help_text= 'Note: the user must also be given separate access to AWS QuickSight via DIT SSO', required=False, ) authorized_master_datasets = forms.ModelMultipleChoiceField( required=False, widget=FilteredSelectMultiple('master datasets', False), queryset=MasterDataset.objects.live().filter( user_access_type='REQUIRES_AUTHORIZATION').order_by('name'), ) authorized_data_cut_datasets = forms.ModelMultipleChoiceField( required=False, widget=FilteredSelectMultiple('data cut datasets', False), queryset=DataCutDataset.objects.live().filter( user_access_type='REQUIRES_AUTHORIZATION').order_by('name'), ) authorized_visualisations = forms.ModelMultipleChoiceField( label='Authorized visualisations', required=False, widget=FilteredSelectMultiple('visualisations', False), queryset=None, ) class Meta: model = get_user_model() fields = '__all__' def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) instance = kwargs['instance'] self.fields[ 'home_directory_efs_access_point_id'].initial = instance.profile.home_directory_efs_access_point_id self.fields['home_directory_efs_access_point_id'].widget.attrs[ 'class'] = 'vTextField' self.fields[ 'can_start_all_applications'].initial = instance.user_permissions.filter( codename='start_all_applications', content_type=ContentType.objects.get_for_model( ApplicationInstance), ).exists() self.fields[ 'can_develop_visualisations'].initial = instance.user_permissions.filter( codename='develop_visualisations', content_type=ContentType.objects.get_for_model( ApplicationInstance), ).exists() self.fields[ 'can_access_appstream'].initial = instance.user_permissions.filter( codename='access_appstream', content_type=ContentType.objects.get_for_model( ApplicationInstance), ).exists() self.fields[ 'can_access_quicksight'].initial = instance.user_permissions.filter( codename='access_quicksight', content_type=ContentType.objects.get_for_model( ApplicationInstance), ).exists() self.fields[ 'authorized_master_datasets'].initial = MasterDataset.objects.live( ).filter(datasetuserpermission__user=instance) self.fields[ 'authorized_data_cut_datasets'].initial = DataCutDataset.objects.live( ).filter(datasetuserpermission__user=instance) self.fields[ 'authorized_visualisations'].initial = VisualisationCatalogueItem.objects.live( ).filter(visualisationuserpermission__user=instance) self.fields[ 'authorized_visualisations'].queryset = VisualisationCatalogueItem.objects.live( ).order_by('name', 'id')
class BaseDynamicEntityForm(ModelForm): """ ModelForm for entity with support for EAV attributes. Form fields are created on the fly depending on Schema defined for given entity instance. If no schema is defined (i.e. the entity instance has not been saved yet), only static fields are used. However, on form validation the schema will be retrieved and EAV fields dynamically added to the form, so when the validation is actually done, all EAV fields are present in it (unless Rubric is not defined). """ FIELD_CLASSES = { 'text': CharField, 'float': FloatField, 'date': DateField, 'bool': BooleanField, 'many': ModelMultipleChoiceField, #RelatedFieldWidgetWrapper(MultipleChoiceField), 'range': RangeField, } FIELD_EXTRA = { 'date': { 'widget': AdminDateWidget }, 'many': lambda schema: { 'widget': CheckboxSelectMultiple if len(schema.get_choices()) <= 5 else FilteredSelectMultiple(schema.title, is_stacked=False) }, } def __init__(self, data=None, *args, **kwargs): super(BaseDynamicEntityForm, self).__init__(data, *args, **kwargs) self._build_dynamic_fields() def check_eav_allowed(self): """ Returns True if dynamic attributes can be added to this form. If False is returned, only normal fields will be displayed. """ return bool( self.instance ) # and self.instance.check_eav_allowed()) # XXX would break form where stuff is _being_ defined def _build_dynamic_fields(self): # reset form fields self.fields = deepcopy(self.base_fields) # do not display dynamic fields if some fields are yet defined if not self.check_eav_allowed(): return for schema in self.instance.get_schemata(): defaults = { 'label': schema.title.capitalize(), 'required': schema.required, 'help_text': schema.help_text, } datatype = schema.datatype if datatype == schema.TYPE_MANY: choices = getattr(self.instance, schema.name) defaults.update({ 'queryset': schema.get_choices(), 'initial': [x.pk for x in choices] }) extra = self.FIELD_EXTRA.get(datatype, {}) if hasattr(extra, '__call__'): extra = extra(schema) defaults.update(extra) MappedField = self.FIELD_CLASSES[datatype] self.fields[schema.name] = MappedField(**defaults) # fill initial data (if attribute was already defined) value = getattr(self.instance, schema.name) if value and not datatype == schema.TYPE_MANY: # m2m is already done above self.initial[schema.name] = value def save(self, commit=True): """ Saves this ``form``'s cleaned_data into model instance ``self.instance`` and related EAV attributes. Returns ``instance``. """ if self.errors: raise ValueError( "The %s could not be saved because the data didn't" " validate." % self.instance._meta.object_name) # create entity instance, don't save yet instance = super(BaseDynamicEntityForm, self).save(commit=False) # assign attributes for name in instance.get_schema_names(): value = self.cleaned_data.get(name) setattr(instance, name, value) # save entity and its attributes if commit: instance.save() return instance save.alters_data = True def save_m2m(self, *a, **kw): # stub for admin TODO: check if we don't need to super() if entity indeed has m2m pass
def formfield_for_manytomany(self, db_field, request=None, **kwargs): kwargs['widget'] = FilteredSelectMultiple(db_field.verbose_name, is_stacked=False) return super(ModelViewAdminMixin, self).formfield_for_manytomany(db_field, request, **kwargs)
def formfield_for_manytomany(self, db_field, request=None, **kwargs): if db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)): kwargs['widget'] = FilteredSelectMultiple( db_field.verbose_name, (db_field.name in self.filter_vertical)) return db_field.formfield(**kwargs)
def get_obj_perms_field_widget(self): return FilteredSelectMultiple(_("Permissions"), False)
def render(self, name, value, attrs=None, renderer=None): choices = self.choices apps_available = [] # main container to send to template user_permissions = Permission.objects.filter( id__in=value or []).values_list('id', flat=True) all_perms = Permission.objects.all().values( 'id', 'codename', 'content_type_id').order_by('codename') excluded_perms = set([]) codename_id_map = {} for p in all_perms: codename_id_map['%s_%s' % (p['codename'], p['content_type_id'])] = p['id'] reminder_perms = codename_id_map.copy() # used to detect if the tabular permissions covers all permissions, if so, we don't need to make it visible. for app in apps.get_app_configs(): app_dict = { 'verbose_name': force_text(app.verbose_name), 'models': [] } for model_name in app.models: model = app.models[model_name] ct_id = ContentType.objects.get_for_model( model, for_concrete_model=TABULAR_PERMISSIONS_USE_FOR_CONCRETE).pk add_perm_name = get_perm_name(model_name, 'add') change_perm_name = get_perm_name(model_name, 'change') delete_perm_name = get_perm_name(model_name, 'delete') add_perm_id = codename_id_map.get( '%s_%s' % (add_perm_name, ct_id), False) change_perm_id = codename_id_map.get( '%s_%s' % (change_perm_name, ct_id), False) delete_perm_id = codename_id_map.get( '%s_%s' % (delete_perm_name, ct_id), False) if add_perm_id and change_perm_id and delete_perm_id and not { add_perm_id, change_perm_id, delete_perm_id } & excluded_perms: excluded_perms.update( [add_perm_id, change_perm_id, delete_perm_id]) reminder_perms.pop('%s_%s' % (add_perm_name, ct_id)) reminder_perms.pop('%s_%s' % (change_perm_name, ct_id)) reminder_perms.pop('%s_%s' % (delete_perm_name, ct_id)) if app.label in TABULAR_PERMISSIONS_EXCLUDE_APPS \ or model_name in TABULAR_PERMISSIONS_EXCLUDE_MODELS \ or TABULAR_PERMISSIONS_EXCLUDE_FUNCTION()(model): continue app_dict['models'].append({ 'model_name': model_name, 'model': model, 'verbose_name_plural': force_text(model._meta.verbose_name_plural), 'verbose_name': force_text(model._meta.verbose_name), 'add_perm_id': add_perm_id, 'add_perm_name': add_perm_name, 'change_perm_id': change_perm_id, 'change_perm_name': change_perm_name, 'delete_perm_id': delete_perm_id, 'delete_perm_name': delete_perm_name, }) if app.models: apps_available.append(app_dict) request_context = { 'apps_available': apps_available, 'user_permissions': user_permissions, 'codename_id_map': codename_id_map, 'input_name': self.input_name } body = get_template(TABULAR_PERMISSIONS_TEMPLATE).render( request_context).encode("utf-8") self.managed_perms = excluded_perms if reminder_perms: self.hide_original = False reminder_choices = get_reminder_permissions_iterator( choices, reminder_perms) if not reminder_choices: attrs['style'] = " display:none " # switching to "normal" SelectMultiple as FilteredSelectMultiple will render the widget even # if the style=display:none original_class = SelectMultiple(attrs, reminder_choices) else: original_class = FilteredSelectMultiple(self.verbose_name, self.is_stacked, attrs, reminder_choices) output = original_class.render(name, value, attrs, renderer) initial = mark_safe(''.join(output)) response = ' <hr/>'.join([force_text(body), force_text(initial)]) return mark_safe(response)