class SearchFilter(filters.FilterSet): """An unusually complicated search filter, which does extra filtering on nicknames, default and non-default contact details, unaccented filtering """ def filter_firstname(self, queryset, field_name, value) -> models.QuerySet: """Filters on firstname or nickname, accent-insensitive""" return queryset.filter( models.Q(firstname__unaccent__startswith=value) | models.Q(nickname__unaccent__startswith=value) ) firstname = filters.CharFilter(label='First name', method='filter_firstname') surname = filters.CharFilter( label='Surname', field_name='surname', lookup_expr='unaccent__startswith', ) birthdate = filters.DateFilter(label='Birthdate', field_name='birthdate', widget=DatePickerInput()) def filter_postcode(self, queryset, field_name, value) -> models.QuerySet: """Finds postcodes starting the same way, while removing spaces from the search and target""" value = re.sub(r'\s+', '', value) return queryset.annotate( trimmed_postcode=Replace('default_address__postcode', models.Value(' '), models.Value('')) ).filter( trimmed_postcode__startswith=value, ) postcode = filters.CharFilter( label='Postcode', method='filter_postcode', ) def filter_email(self, queryset, field_name, value) -> models.QuerySet: """Filters on (any) email address, and adds an extra column for the result table to use""" return ( queryset.filter(email__email__contains=value) .annotate( email_address=models.F('email__email'), ) .distinct() ) email = filters.CharFilter( label='Email', method='filter_email', ) def filter_phone(self, queryset, field_name, value) -> models.QuerySet: """Filters on (any) phone number, and adds an extra column for the result table to use""" value = re.sub(r'\s+', '', value) return ( queryset.annotate(phone_number=models.F('phones__number')) # for table display .alias(stripped_phone_number=Replace('phones__number', models.Value(' '), models.Value(''))) .filter(stripped_phone_number__contains=value) .distinct() ) phone = filters.CharFilter( label='Phone', method='filter_phone', ) def filter_tutors_only(self, queryset, field_name, value) -> models.QuerySet: if value: return queryset.filter(tutor__id__isnull=False) return queryset tutors_only = filters.BooleanFilter( label='Tutors only?', method='filter_tutors_only', widget=forms.CheckboxInput, ) class Meta: model = Student fields = ('firstname', 'surname', 'birthdate', 'postcode', 'phone', 'email', 'tutors_only')
class PostAdminWithFilterInstances(djadmin2.ModelAdmin2): list_filter = [ django_filters.BooleanFilter(name='published'), ]
class ProjectFilter(django_filters.FilterSet): project_institutions = django_filters.ModelChoiceFilter( label=FieldProject.INSTITUTION, queryset=Institution.objects.all(), widget=autocomplete.ModelSelect2(url='institution-autocomplete')) project_participants = django_filters.ModelChoiceFilter( label=FieldProject.PARTICIPANTS, queryset=Person.objects.all(), widget=autocomplete.ModelSelect2(url='person-autocomplete')) project_title_text = django_filters.CharFilter( label=FieldProject.TITLE, lookup_expr='icontains', widget=forms.TextInput(attrs={'class': 'list__form--input'})) project_targets = django_filters.ModelMultipleChoiceFilter( label=FieldProject.TARGETS, queryset=TargetGroup.objects.all(), widget=autocomplete.ModelSelect2Multiple( url='targetgroup-autocomplete')) project_disciplines = django_filters.ModelChoiceFilter( label=FieldProject.DISCIPLINES, queryset=ResearchDiscipline.objects.all(), widget=autocomplete.ModelSelect2( url='researchdiscipline-autocomplete')) project_cities__region = django_filters.ModelChoiceFilter( label=FieldProject.REGIONS, queryset=Region.objects.all(), widget=autocomplete.ModelSelect2(url='region-autocomplete')) project_cities = django_filters.ModelChoiceFilter( label=FieldProject.CITIES, queryset=City.objects.all(), widget=autocomplete.ModelSelect2(url='city-autocomplete')) project_date_start = django_filters.DateFilter( label=FieldProject.DATE_START, lookup_expr='gte', widget=forms.DateTimeInput( attrs={'class': 'datepicker list__form--input'})) project_date_end = django_filters.DateFilter( label=FieldProject.DATE_END, lookup_expr='lte', widget=forms.DateTimeInput( attrs={'class': 'datepicker list__form--input'})) project_financing = django_filters.CharFilter( label=FieldProject.FINANCING, lookup_expr='icontains', widget=forms.TextInput(attrs={'class': 'list__form--input'})) project_keywords = django_filters.ModelMultipleChoiceFilter( label=FieldProject.KEYWORDS, queryset=Tag.objects.all(), widget=autocomplete.ModelSelect2Multiple(url='tag-autocomplete')) project_is_accepted = django_filters.BooleanFilter( label=FieldProject.IS_ACCEPTED, widget=NullBooleanSelect(attrs={'class': 'select2'})) o = django_filters.OrderingFilter(fields=( ('project_is_promoted', 'project_is_promoted'), ('project_date_add', 'project_date_add'), ('project_title_text', 'project_title_text'), ('project_date_end', 'project_date_end'), ), ) strict = True class Meta: model = Project form = ProjectFilterForm fields = [ 'project_institutions', 'project_participants', 'project_title_text', 'project_targets', 'project_disciplines', 'project_cities__region', 'project_cities', 'project_date_start', 'project_date_end', 'project_financing', 'project_keywords', 'project_is_accepted' ]
class LeadGQFilterSet(UserResourceGqlFilterSet): ids = IDListFilter(method='filter_leads_id', help_text='Empty ids are ignored.') exclude_provided_leads_id = django_filters.BooleanFilter( method='filter_exclude_provided_leads_id', help_text='Only used when ids are provided.') created_by = IDListFilter() modified_by = IDListFilter() source_types = MultipleInputFilter(LeadSourceTypeEnum, field_name='source_type') priorities = MultipleInputFilter(LeadPriorityEnum, field_name='priority') confidentiality = SimpleInputFilter(LeadConfidentialityEnum) statuses = MultipleInputFilter(LeadStatusEnum, field_name='status') extraction_status = SimpleInputFilter(LeadExtractionStatusEnum, field_name='extraction_status') assignees = IDListFilter(field_name='assignee') authoring_organization_types = IDListFilter(method='authoring_organization_types_filter') author_organizations = IDListFilter(method='authoring_organizations_filter') source_organizations = IDListFilter(method='source_organizations_filter') # Filter-only enum filter has_entries = django_filters.BooleanFilter(method='filter_has_entries', help_text='Lead has entries.') has_assessment = django_filters.BooleanFilter(method='filter_has_assessment', help_text='Lead has assessment.') entries_filter_data = SimpleInputFilter( type( 'LeadEntriesFilterData', (graphene.InputObjectType,), get_filtering_args_from_filterset(EntryGQFilterSet, 'entry.schema.EntryListType') ), method='filtered_entries_filter_data', ) search = django_filters.CharFilter(method='search_filter') published_on = django_filters.DateFilter() published_on_gte = DateGteFilter(field_name='published_on') published_on_lte = DateLteFilter(field_name='published_on') emm_entities = django_filters.CharFilter(method='emm_entities_filter') emm_keywords = django_filters.CharFilter(method='emm_keywords_filter') emm_risk_factors = django_filters.CharFilter(method='emm_risk_factors_filter') ordering = MultipleInputFilter(LeadOrderingEnum, method='ordering_filter') class Meta: model = Lead fields = { **{ x: ['exact'] for x in ['text', 'url'] }, } filter_overrides = { models.CharField: { 'filter_class': django_filters.CharFilter, 'extra': lambda _: { 'lookup_expr': 'icontains', }, }, } def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.custom_context = {} @property def active_project(self) -> Project: if self.request is None: raise Exception(f'{self.request=} should be defined') if self.request.active_project is None: raise Exception(f'{self.request.active_project=} should be defined') return self.request.active_project @staticmethod def get_dummy_request(project): """ Use this if request is not available """ return type('DummyRequest', (object,), dict(active_project=project))() # Filters methods def search_filter(self, qs, name, value): # NOTE: This exists to make it compatible with post filter if not value: return qs return qs.filter( # By title models.Q(title__icontains=value) | # By source models.Q(source_raw__icontains=value) | models.Q(source__title__icontains=value) | models.Q(source__parent__title__icontains=value) | # By author models.Q(author__title__icontains=value) | models.Q(author__parent__title__icontains=value) | models.Q(author_raw__icontains=value) | models.Q(authors__title__icontains=value) | models.Q(authors__parent__title__icontains=value) | # By URL models.Q(url__icontains=value) ).distinct() def ordering_filter(self, qs, name, value): active_entry_count_field = self.custom_context.get('active_entry_count_field') for ordering in value: # Custom for entries count (use filter or normal entry count) if active_entry_count_field and ordering in [ LeadOrderingEnum.ASC_ENTRIES_COUNT, LeadOrderingEnum.DESC_ENTRIES_COUNT, ]: if ordering == LeadOrderingEnum.ASC_ENTRIES_COUNT: qs = qs.order_by(active_entry_count_field) else: qs = qs.order_by(f'-{active_entry_count_field}') # Custom for page count with nulls_last elif ordering == LeadOrderingEnum.DESC_PAGE_COUNT: qs = qs.order_by(models.F('leadpreview__page_count').desc(nulls_last=True)) elif ordering == LeadOrderingEnum.ASC_PAGE_COUNT: qs = qs.order_by(models.F('leadpreview__page_count').asc(nulls_first=True)) # For remaining else: qs = qs.order_by(ordering) return qs def emm_entities_filter(self, qs, name, value): splitted = [x for x in value.split(',') if x] return qs.filter(emm_entities__in=splitted) def emm_keywords_filter(self, qs, name, value): splitted = [x for x in value.split(',') if x] return qs.filter(emm_triggers__emm_keyword__in=splitted) def emm_risk_factors_filter(self, qs, name, value): splitted = [x for x in value.split(',') if x] return qs.filter(emm_triggers__emm_risk_factor__in=splitted) def authoring_organization_types_filter(self, qs, name, value): if value: qs = qs.annotate( organization_types=Coalesce( 'authors__parent__organization_type', 'authors__organization_type' ) ) if type(value[0]) == OrganizationType: return qs.filter(organization_types__in=[ot.id for ot in value]).distinct() return qs.filter(organization_types__in=value).distinct() return qs def authoring_organizations_filter(self, qs, _, value): if value: qs = qs.annotate(authoring_organizations=Coalesce('authors__parent_id', 'authors__id')) return qs.filter(authoring_organizations__in=value).distinct() return qs def source_organizations_filter(self, qs, _, value): if value: qs = qs.annotate(source_organizations=Coalesce('source__parent_id', 'source__id')) return qs.filter(source_organizations__in=value).distinct() return qs def filter_exclude_provided_leads_id(self, qs, *_): # NOTE: Used in filter_leads_id return qs def filter_leads_id(self, qs, _, value): if value is None: return qs if self.data.get('exclude_provided_leads_id'): return qs.exclude(id__in=value) return qs.filter(id__in=value) def filter_has_entries(self, qs, _, value): if value is None: return qs if value: return qs.filter(entry_count__gt=0) return qs.filter(entry_count=0) def filter_has_assessment(self, qs, _, value): if value is None: return qs return qs.filter(assessment__isnull=not value) def filtered_entries_filter_data(self, qs, _, value): if value is None: return qs return qs.filter(filtered_entry_count__gt=0) def filter_queryset(self, qs): def _entry_subquery(entry_qs: models.QuerySet): subquery_qs = entry_qs.\ filter( project=self.active_project, analysis_framework=self.active_project.analysis_framework_id, lead=models.OuterRef('pk'), )\ .values('lead').order_by()\ .annotate(count=models.Count('id'))\ .values('count') return Coalesce( models.Subquery( subquery_qs[:1], output_field=models.IntegerField() ), 0, ) # Pre-annotate required fields for entries count (w/wo filters) entries_filter_data = self.data.get('entries_filter_data') has_entries = self.data.get('has_entries') has_entries_count_ordering = any( ordering in [ LeadOrderingEnum.ASC_ENTRIES_COUNT, LeadOrderingEnum.DESC_ENTRIES_COUNT, ] for ordering in self.data.get('ordering') or [] ) # With filter if entries_filter_data is not None: qs = qs.annotate( filtered_entry_count=_entry_subquery( EntryGQFilterSet( data=entries_filter_data, request=self.request, ).qs ) ) self.custom_context['active_entry_count_field'] = 'filtered_entry_count' # Without filter if has_entries is not None or ( entries_filter_data is None and has_entries_count_ordering ): self.custom_context['active_entry_count_field'] = self.custom_context.\ get('active_entry_count_field', 'entry_count') qs = qs.annotate( entry_count=_entry_subquery(Entry.objects.all()) ) # Call super function return super().filter_queryset(qs) @property def qs(self): return super().qs.distinct()
class OfferingFilter(structure_filters.NameFilterSet, django_filters.FilterSet): class Meta: model = models.Offering fields = [] customer = core_filters.URLFilter(view_name='customer-detail', field_name='customer__uuid') customer_uuid = django_filters.UUIDFilter(field_name='customer__uuid') allowed_customer_uuid = django_filters.UUIDFilter( method='filter_allowed_customer') service_manager_uuid = django_filters.UUIDFilter( method='filter_service_manager') project_uuid = django_filters.UUIDFilter(method='filter_project') attributes = django_filters.CharFilter(method='filter_attributes') state = core_filters.MappedMultipleChoiceFilter( choices=[(representation, representation) for db_value, representation in models.Offering.States.CHOICES ], choice_mappings={ representation: db_value for db_value, representation in models.Offering.States.CHOICES }, ) category_uuid = django_filters.UUIDFilter(field_name='category__uuid') billable = django_filters.BooleanFilter(widget=BooleanWidget) shared = django_filters.BooleanFilter(widget=BooleanWidget) description = django_filters.CharFilter(lookup_expr='icontains') keyword = django_filters.CharFilter(method='filter_keyword', label='Keyword') o = django_filters.OrderingFilter(fields=('name', 'created', 'type')) type = LooseMultipleChoiceFilter() def filter_allowed_customer(self, queryset, name, value): return queryset.filter_for_customer(value) def filter_service_manager(self, queryset, name, value): return queryset.filter_for_service_manager(value) def filter_project(self, queryset, name, value): return queryset.filter_for_project(value) def filter_attributes(self, queryset, name, value): try: value = json.loads(value) except ValueError: raise rf_exceptions.ValidationError( _('Filter attribute is not valid json.')) if not isinstance(value, dict): raise rf_exceptions.ValidationError( _('Filter attribute should be an dict.')) for k, v in value.items(): if isinstance(v, list): # If a filter value is a list, use multiple choice. queryset = queryset.filter( **{'attributes__{key}__has_any_keys'.format(key=k): v}) else: queryset = queryset.filter(attributes__contains={k: v}) return queryset def filter_keyword(self, queryset, name, value): return queryset.filter( Q(name__icontains=value) | Q(description__icontains=value) | Q(customer__name__icontains=value) | Q(customer__abbreviation__icontains=value) | Q(customer__native_name__icontains=value))
class DeviceFilterSet( BaseFilterSet, TenancyFilterSet, LocalConfigContextFilterSet, CustomFieldModelFilterSet, CreatedUpdatedFilterSet ): q = django_filters.CharFilter( method='search', label='Search', ) manufacturer_id = django_filters.ModelMultipleChoiceFilter( field_name='device_type__manufacturer', queryset=Manufacturer.objects.all(), label='Manufacturer (ID)', ) manufacturer = django_filters.ModelMultipleChoiceFilter( field_name='device_type__manufacturer__slug', queryset=Manufacturer.objects.all(), to_field_name='slug', label='Manufacturer (slug)', ) device_type_id = django_filters.ModelMultipleChoiceFilter( queryset=DeviceType.objects.all(), label='Device type (ID)', ) role_id = django_filters.ModelMultipleChoiceFilter( field_name='device_role_id', queryset=DeviceRole.objects.all(), label='Role (ID)', ) role = django_filters.ModelMultipleChoiceFilter( field_name='device_role__slug', queryset=DeviceRole.objects.all(), to_field_name='slug', label='Role (slug)', ) platform_id = django_filters.ModelMultipleChoiceFilter( queryset=Platform.objects.all(), label='Platform (ID)', ) platform = django_filters.ModelMultipleChoiceFilter( field_name='platform__slug', queryset=Platform.objects.all(), to_field_name='slug', label='Platform (slug)', ) region_id = TreeNodeMultipleChoiceFilter( queryset=Region.objects.all(), field_name='site__region', lookup_expr='in', label='Region (ID)', ) region = TreeNodeMultipleChoiceFilter( queryset=Region.objects.all(), field_name='site__region', lookup_expr='in', to_field_name='slug', label='Region (slug)', ) site_id = django_filters.ModelMultipleChoiceFilter( queryset=Site.objects.all(), label='Site (ID)', ) site = django_filters.ModelMultipleChoiceFilter( field_name='site__slug', queryset=Site.objects.all(), to_field_name='slug', label='Site name (slug)', ) rack_group_id = TreeNodeMultipleChoiceFilter( queryset=RackGroup.objects.all(), field_name='rack__group', lookup_expr='in', label='Rack group (ID)', ) rack_id = django_filters.ModelMultipleChoiceFilter( field_name='rack', queryset=Rack.objects.all(), label='Rack (ID)', ) cluster_id = django_filters.ModelMultipleChoiceFilter( queryset=Cluster.objects.all(), label='VM cluster (ID)', ) model = django_filters.ModelMultipleChoiceFilter( field_name='device_type__slug', queryset=DeviceType.objects.all(), to_field_name='slug', label='Device model (slug)', ) status = django_filters.MultipleChoiceFilter( choices=DeviceStatusChoices, null_value=None ) is_full_depth = django_filters.BooleanFilter( field_name='device_type__is_full_depth', label='Is full depth', ) mac_address = MultiValueMACAddressFilter( field_name='interfaces__mac_address', label='MAC address', ) serial = django_filters.CharFilter( lookup_expr='iexact' ) has_primary_ip = django_filters.BooleanFilter( method='_has_primary_ip', label='Has a primary IP', ) virtual_chassis_id = django_filters.ModelMultipleChoiceFilter( field_name='virtual_chassis', queryset=VirtualChassis.objects.all(), label='Virtual chassis (ID)', ) virtual_chassis_member = django_filters.BooleanFilter( method='_virtual_chassis_member', label='Is a virtual chassis member' ) console_ports = django_filters.BooleanFilter( method='_console_ports', label='Has console ports', ) console_server_ports = django_filters.BooleanFilter( method='_console_server_ports', label='Has console server ports', ) power_ports = django_filters.BooleanFilter( method='_power_ports', label='Has power ports', ) power_outlets = django_filters.BooleanFilter( method='_power_outlets', label='Has power outlets', ) interfaces = django_filters.BooleanFilter( method='_interfaces', label='Has interfaces', ) pass_through_ports = django_filters.BooleanFilter( method='_pass_through_ports', label='Has pass-through ports', ) device_bays = django_filters.BooleanFilter( method='_device_bays', label='Has device bays', ) tag = TagFilter() class Meta: model = Device fields = ['id', 'name', 'asset_tag', 'face', 'position', 'vc_position', 'vc_priority'] def search(self, queryset, name, value): if not value.strip(): return queryset return queryset.filter( Q(name__icontains=value) | Q(serial__icontains=value.strip()) | Q(inventoryitems__serial__icontains=value.strip()) | Q(asset_tag__icontains=value.strip()) | Q(comments__icontains=value) ).distinct() def _has_primary_ip(self, queryset, name, value): params = Q(primary_ip4__isnull=False) | Q(primary_ip6__isnull=False) if value: return queryset.filter(params) return queryset.exclude(params) def _virtual_chassis_member(self, queryset, name, value): return queryset.exclude(virtual_chassis__isnull=value) def _console_ports(self, queryset, name, value): return queryset.exclude(consoleports__isnull=value) def _console_server_ports(self, queryset, name, value): return queryset.exclude(consoleserverports__isnull=value) def _power_ports(self, queryset, name, value): return queryset.exclude(powerports__isnull=value) def _power_outlets(self, queryset, name, value): return queryset.exclude(poweroutlets__isnull=value) def _interfaces(self, queryset, name, value): return queryset.exclude(interfaces__isnull=value) def _pass_through_ports(self, queryset, name, value): return queryset.exclude( frontports__isnull=value, rearports__isnull=value ) def _device_bays(self, queryset, name, value): return queryset.exclude(devicebays__isnull=value)
class MonsterFilter(django_filters.FilterSet): name = django_filters.CharFilter(method='filter_name') element = django_filters.MultipleChoiceFilter( choices=Monster.ELEMENT_CHOICES) archetype = django_filters.MultipleChoiceFilter( choices=Monster.TYPE_CHOICES) awaken_level = django_filters.MultipleChoiceFilter( choices=Monster.AWAKEN_CHOICES) leader_skill__attribute = django_filters.MultipleChoiceFilter( choices=LeaderSkill.ATTRIBUTE_CHOICES) leader_skill__area = django_filters.MultipleChoiceFilter( choices=LeaderSkill.AREA_CHOICES) skills__scaling_stats__pk = django_filters.ModelMultipleChoiceFilter( queryset=ScalingStat.objects.all(), to_field_name='pk', conjoined=True) skills__cooltime = django_filters.CharFilter( method='filter_skills_cooltime') effects_logic = django_filters.BooleanFilter(method='filter_effects_logic') skills__skill_effect__pk = django_filters.ModelMultipleChoiceFilter( queryset=SkillEffect.objects.all(), method='filter_skill_effects') class Meta: model = Monster fields = { 'name': ['exact'], 'com2us_id': ['exact'], 'family_id': ['exact'], 'element': ['exact'], 'archetype': ['exact'], 'base_stars': ['lte', 'gte'], 'natural_stars': ['lte', 'gte'], 'obtainable': ['exact'], 'awaken_level': ['exact'], 'leader_skill__attribute': ['exact'], 'leader_skill__area': ['exact'], 'skills__skill_effect__pk': ['exact'], 'skills__scaling_stats__pk': ['exact'], 'skills__cooltime': ['lte', 'gte'], 'skills__hits': ['lte', 'gte'], 'effects_logic': ['exact'], 'fusion_food': ['exact'], } def filter_name(self, queryset, name, value): if value: return queryset.filter( Q(name__icontains=value) | Q(awakens_from__name__icontains=value) | Q(awakens_to__name__icontains=value)) else: return queryset def filter_skill_effects(self, queryset, name, value): old_filtering = self.form.cleaned_data.get('effects_logic', False) stat_scaling = self.form.cleaned_data.get('skills__scaling_stats__pk', []) cooltimes = self.form.cleaned_data.get('skills__cooltime', '') max_num_hits = self.form.cleaned_data.get('skills__hits__lte', 99) min_num_hits = self.form.cleaned_data.get('skills__hits__gte', 0) try: cooltimes = cooltimes.split(',') min_cooltime = int(cooltimes[0]) max_cooltime = int(cooltimes[1]) except: min_cooltime = 0 max_cooltime = 999 if old_filtering: # Filter if any skill on the monster has the designated fields for effect in value: queryset = queryset.filter(skills__skill_effect=effect) for pk in stat_scaling: queryset = queryset.filter(skills__scaling_stats=pk) cooltime_filter = Q(skills__cooltime__gte=min_cooltime) & Q( skills__cooltime__lte=max_cooltime) if min_cooltime == 0 or max_cooltime == 0: cooltime_filter = Q( skills__cooltime__isnull=True) | cooltime_filter queryset = queryset.filter(cooltime_filter, skills__hits__lte=max_num_hits, skills__hits__gte=min_num_hits) return queryset.distinct() else: # Filter effects based on effects of each individual skill. This ensures a monster will not show up unless it has # the desired effects on the same skill rather than across any skills. skills = Skill.objects.all() for effect in value: skills = skills.filter(skill_effect=effect) for pk in stat_scaling: skills = skills.filter(scaling_stats=pk) cooltime_filter = Q(cooltime__gte=min_cooltime) & Q( cooltime__lte=max_cooltime) if min_cooltime == 0 or max_cooltime == 0: cooltime_filter = Q(cooltime__isnull=True) | cooltime_filter skills = skills.filter(cooltime_filter, hits__lte=max_num_hits, hits__gte=min_num_hits) return queryset.filter(skills__in=skills).distinct() def filter_effects_logic(self, queryset, name, value): # This field is just used to alter the logic of skill effect filter return queryset def filter_skills_cooltime(self, queryset, name, value): # This field is handled in filter_skill_effects() return queryset def filter_skills_slot(self, queryset, name, value): # This field is handled in filter_skill_effects() return queryset def filter_skills_hits(self, queryset, name, value): # This field is handled in filter_skill_effects() return queryset
class VirtualMachineFilterSet( BaseFilterSet, LocalConfigContextFilterSet, TenancyFilterSet, CustomFieldModelFilterSet, CreatedUpdatedFilterSet ): q = django_filters.CharFilter( method='search', label='Search', ) status = django_filters.MultipleChoiceFilter( choices=VirtualMachineStatusChoices, null_value=None ) cluster_group_id = django_filters.ModelMultipleChoiceFilter( field_name='cluster__group', queryset=ClusterGroup.objects.all(), label='Cluster group (ID)', ) cluster_group = django_filters.ModelMultipleChoiceFilter( field_name='cluster__group__slug', queryset=ClusterGroup.objects.all(), to_field_name='slug', label='Cluster group (slug)', ) cluster_type_id = django_filters.ModelMultipleChoiceFilter( field_name='cluster__type', queryset=ClusterType.objects.all(), label='Cluster type (ID)', ) cluster_type = django_filters.ModelMultipleChoiceFilter( field_name='cluster__type__slug', queryset=ClusterType.objects.all(), to_field_name='slug', label='Cluster type (slug)', ) cluster_id = django_filters.ModelMultipleChoiceFilter( queryset=Cluster.objects.all(), label='Cluster (ID)', ) region_id = TreeNodeMultipleChoiceFilter( queryset=Region.objects.all(), field_name='cluster__site__region', lookup_expr='in', label='Region (ID)', ) region = TreeNodeMultipleChoiceFilter( queryset=Region.objects.all(), field_name='cluster__site__region', lookup_expr='in', to_field_name='slug', label='Region (slug)', ) site_group_id = TreeNodeMultipleChoiceFilter( queryset=SiteGroup.objects.all(), field_name='cluster__site__group', lookup_expr='in', label='Site group (ID)', ) site_group = TreeNodeMultipleChoiceFilter( queryset=SiteGroup.objects.all(), field_name='cluster__site__group', lookup_expr='in', to_field_name='slug', label='Site group (slug)', ) site_id = django_filters.ModelMultipleChoiceFilter( field_name='cluster__site', queryset=Site.objects.all(), label='Site (ID)', ) site = django_filters.ModelMultipleChoiceFilter( field_name='cluster__site__slug', queryset=Site.objects.all(), to_field_name='slug', label='Site (slug)', ) role_id = django_filters.ModelMultipleChoiceFilter( queryset=DeviceRole.objects.all(), label='Role (ID)', ) role = django_filters.ModelMultipleChoiceFilter( field_name='role__slug', queryset=DeviceRole.objects.all(), to_field_name='slug', label='Role (slug)', ) platform_id = django_filters.ModelMultipleChoiceFilter( queryset=Platform.objects.all(), label='Platform (ID)', ) platform = django_filters.ModelMultipleChoiceFilter( field_name='platform__slug', queryset=Platform.objects.all(), to_field_name='slug', label='Platform (slug)', ) mac_address = MultiValueMACAddressFilter( field_name='interfaces__mac_address', label='MAC address', ) has_primary_ip = django_filters.BooleanFilter( method='_has_primary_ip', label='Has a primary IP', ) tag = TagFilter() class Meta: model = VirtualMachine fields = ['id', 'name', 'cluster', 'vcpus', 'memory', 'disk'] def search(self, queryset, name, value): if not value.strip(): return queryset return queryset.filter( Q(name__icontains=value) | Q(comments__icontains=value) ) def _has_primary_ip(self, queryset, name, value): params = Q(primary_ip4__isnull=False) | Q(primary_ip6__isnull=False) if value: return queryset.filter(params) return queryset.exclude(params)
class RangeFilter(django_filters.FilterSet): start_date = django_filters.DateFilter( field_name='date', lookup_expr='gt', input_formats=['%Y-%m-%d', '%d-%m-%Y', '%m-%Y', '%Y']) end_date = django_filters.DateFilter( field_name='date', lookup_expr='lt', input_formats=['%Y-%m-%d', '%d-%m-%Y', '%m-%Y', '%Y']) date = django_filters.DateFilter( field_name='date', lookup_expr='contains', input_formats=['%Y-%m-%d', '%d-%m-%Y', '%m-%Y', '%Y']) os = django_filters.CharFilter(field_name='os', lookup_expr='icontains', label="Os") country = django_filters.CharFilter(field_name='country', lookup_expr='icontains', label="Country") annotate = django_filters.CharFilter(method='fields_annotate', label='annotate') fields = django_filters.CharFilter(method='fields_selected', label='fields') cpi = django_filters.BooleanFilter(method='cpi_display', label='cpi') class Meta: model = Metric fields = ('start_date', 'end_date', 'date', 'os', 'country', 'annotate', 'fields', 'cpi') ## filter to annotate fields by it's function such as Max or Count def fields_annotate(self, queryset, value, *args, **kwargs): try: if args: fields = set(args[0].split(',')) valid_fields = list( queryset.values()[0].keys() if queryset.count() else []) valid_prefixes = ['sum', 'max', 'min', 'avg', 'count'] fields_split = [tuple(f.split("_")) for f in fields] fields_to_annotate = dict() for m, field in fields_split: if m in valid_prefixes and field in valid_fields: if field not in list(fields_to_annotate.values()): fields_to_annotate[m] = field if m == "max": queryset = queryset.annotate( **{field + "_": Max(field)}) elif m == "min": queryset = queryset.annotate( **{field + "_": Min(field)}) elif m == "avg": queryset = queryset.annotate( **{field + "_": Avg(field)}) elif m == "sum": queryset = queryset.annotate( **{field + "_": Sum(field)}) elif m == "count": queryset = queryset.annotate( **{field + "_": Count(field)}) except ValueError: pass return queryset # filter to select specific fields. It is also useful to make a group_by annotation def fields_selected(self, queryset, value, *args, **kwargs): try: if args: fields = set(args[0].split(',')) valid_fields = list( queryset.values()[0].keys() if queryset.count() else []) fields_to_lookup = [f for f in fields if f in valid_fields] queryset = queryset.values(*fields_to_lookup) except ValueError: pass return queryset # filter to display to calculate and render the cpi value - cpi = spend / installs def cpi_display(self, queryset, value, *args, **kwargs): from django.db import models from django.db.models import Sum, F try: if args: value = args[0] if value: queryset = queryset.annotate( cpi=Sum(F('spend') / F('installs'), output_field=models.FloatField())) except ValueError: pass return queryset # as dicts are not in order, make sure that annotation filter will get executed last to perform the group_by after values def filter_queryset(self, queryset): cleaned_data = OrderedDict( sorted(self.form.cleaned_data.items(), reverse=True)) fields = cleaned_data.get('fields', None) annotate = cleaned_data.get('annotate', None) if fields is not None and annotate is not None: cleaned_data.move_to_end("annotate") for name, value in cleaned_data.items(): queryset = self.filters[name].filter(queryset, value) assert isinstance(queryset, QuerySet), \ "Expected '%s.%s' to return a QuerySet, but got a %s instead." \ % (type(self).__name__, name, type(queryset).__name__) return queryset
class BaseHookFilter(django_filters.FilterSet): author_uuid = django_filters.UUIDFilter(field_name='user__uuid') is_active = django_filters.BooleanFilter(widget=BooleanWidget) last_published = django_filters.DateTimeFilter()
class MonsterInstanceFilter(django_filters.FilterSet): monster__name = django_filters.CharFilter(method='filter_monster__name') tags__pk = django_filters.ModelMultipleChoiceFilter( queryset=MonsterTag.objects.all(), to_field_name='pk', conjoined=True) monster__element = django_filters.MultipleChoiceFilter( choices=Monster.ELEMENT_CHOICES) monster__archetype = django_filters.MultipleChoiceFilter( choices=Monster.TYPE_CHOICES) monster__awaken_level = django_filters.MultipleChoiceFilter( choices=Monster.AWAKEN_CHOICES) priority = django_filters.MultipleChoiceFilter( choices=MonsterInstance.PRIORITY_CHOICES) monster__leader_skill__attribute = django_filters.MultipleChoiceFilter( choices=LeaderSkill.ATTRIBUTE_CHOICES) monster__leader_skill__area = django_filters.MultipleChoiceFilter( choices=LeaderSkill.AREA_CHOICES) monster__skills__scaling_stats__pk = django_filters.ModelMultipleChoiceFilter( queryset=ScalingStat.objects.all(), to_field_name='pk', conjoined=True) monster__skills__skill_effect__pk = django_filters.ModelMultipleChoiceFilter( queryset=SkillEffect.objects.all(), method='filter_monster__skills__skill_effect__pk') monster__skills__cooltime = django_filters.CharFilter( method='filter_monster_skills_cooltime') effects_logic = django_filters.BooleanFilter(method='filter_effects_logic') monster__fusion_food = django_filters.BooleanFilter( method='filter_monster__fusion_food') class Meta: model = MonsterInstance fields = { 'monster__name': ['exact'], 'tags__pk': ['exact'], 'stars': ['gte', 'lte'], 'level': ['gte', 'lte'], 'monster__element': ['exact'], 'monster__archetype': ['exact'], 'monster__awaken_level': ['exact'], 'priority': ['exact'], 'monster__natural_stars': ['gte', 'lte'], 'monster__leader_skill__attribute': ['exact'], 'monster__leader_skill__area': ['exact'], 'monster__skills__skill_effect__pk': ['exact'], 'monster__skills__scaling_stats__pk': ['exact'], 'monster__skills__hits': ['gte', 'lte'], 'effects_logic': ['exact'], 'fodder': ['exact'], 'in_storage': ['exact'], 'monster__fusion_food': ['exact'], } def filter_monster__name(self, queryset, name, value): if value: return queryset.filter( Q(monster__name__icontains=value) | Q(monster__awakens_from__name__icontains=value)) else: return queryset def filter_monster__fusion_food(self, queryset, name, value): if value: return queryset.filter(monster__fusion_food=True).exclude( ignore_for_fusion=True) else: return queryset.filter( Q(monster__fusion_food=False) | Q(ignore_for_fusion=True)) def filter_monster__skills__skill_effect__pk(self, queryset, name, value): old_filtering = self.form.cleaned_data.get('effects_logic', False) stat_scaling = self.form.cleaned_data.get( 'monster__skills__scaling_stats__pk', []) cooltimes = self.form.cleaned_data.get('monster__skills__cooltime', []) try: cooltimes = cooltimes.split(',') min_cooltime = int(cooltimes[0]) max_cooltime = int(cooltimes[1]) except: min_cooltime = 0 max_cooltime = 999 if old_filtering: # Filter if any skill on the monster has the designated fields for effect in value: queryset = queryset.filter( monster__skills__skill_effect=effect) for pk in stat_scaling: queryset = queryset.filter(monster__skills__scaling_stats=pk) cooltime_filter = Q( monster__skills__cooltime__gte=min_cooltime) & Q( monster__skills__cooltime__lte=max_cooltime) if min_cooltime == 0 or max_cooltime == 0: cooltime_filter = Q( monster__skills__cooltime__isnull=True) | cooltime_filter queryset = queryset.filter(cooltime_filter) return queryset.distinct() else: # Filter effects based on effects of each individual skill. This ensures a monster will not show up unless it has # the desired effects on the same skill rather than across any skills. skills = Skill.objects.all() for effect in value: skills = skills.filter(skill_effect=effect) for pk in stat_scaling: skills = skills.filter(scaling_stats=pk) cooltime_filter = Q(cooltime__gte=min_cooltime) & Q( cooltime__lte=max_cooltime) if min_cooltime == 0 or max_cooltime == 0: cooltime_filter = Q(cooltime__isnull=True) | cooltime_filter skills = skills.filter(cooltime_filter) return queryset.filter(monster__skills__in=skills).distinct() def filter_effects_logic(self, queryset, name, value): # This field is just used to alter the logic of skill effect filter and is used in filter_monster__skills__skill_effect__pk() return queryset def filter_monster_skills_cooltime(self, queryset, name, value): # This field is handled in filter_monster__skills__skill_effect__pk() return queryset
class RuleFilter(django_filters.rest_framework.FilterSet): name = django_filters.CharFilter(field_name="name", lookup_expr="contains") parent = django_filters.CharFilter(field_name="parent__name", lookup_expr="contains") enabled = django_filters.BooleanFilter(field_name="enabled")
class PartnershipAdminFilter(filters.FilterSet): ordering = MultipleOrderingFilter( fields=(('entity__organization__name', 'partner'), ('city', 'city'), ('acronym_path', 'ucl')), multiples={ 'country': ['country_name', 'city', 'entity__organization__name'], }, ) continent = filters.CharFilter(field_name='country_continent_id', method=filter_pk_from_annotation) partnership_type = filters.ChoiceFilter( field_name='partnership__partnership_type', ) supervisor = filters.ModelChoiceFilter( field_name='partnership__supervisor', ) partner_entity = filters.ModelChoiceFilter(field_name='entity') tags = filters.ModelMultipleChoiceFilter(field_name='partnership__tags', ) country = filters.ModelChoiceFilter( field_name='country_id', method=filter_pk_from_annotation, ) city = filters.CharFilter() ucl_entity = filters.ModelChoiceFilter(method='filter_ucl_entity') # This is a noop filter, as its logic is in filter_ucl_entity() ucl_entity_with_child = filters.BooleanFilter(method=lambda qs, *_: qs) partner_type = filters.CharFilter(field_name='entity__organization__type') education_level = filters.CharFilter( field_name='partnership__years__education_levels', ) education_field = filters.CharFilter( field_name='partnership__years__education_fields', ) years_entity = filters.CharFilter(method='filter_years_entity') university_offer = filters.CharFilter(method='filter_university_offer') partner_tags = filters.CharFilter(method='filter_partner_tags') erasmus_code = filters.CharFilter( field_name='entity__organization__partner__erasmus_code', lookup_expr='icontains', ) use_egracons = filters.BooleanFilter( field_name='entity__organization__partner__use_egracons', widget=CustomNullBooleanSelect()) is_sms = filters.BooleanFilter( field_name='partnership__years__is_sms', widget=CustomNullBooleanSelect(), ) is_smp = filters.BooleanFilter( field_name='partnership__years__is_smp', widget=CustomNullBooleanSelect(), ) is_sta = filters.BooleanFilter( field_name='partnership__years__is_sta', widget=CustomNullBooleanSelect(), ) is_stt = filters.BooleanFilter( field_name='partnership__years__is_stt', widget=CustomNullBooleanSelect(), ) is_smst = filters.BooleanFilter( field_name='partnership__years__is_smst', widget=CustomNullBooleanSelect(), ) funding_type = filters.ModelChoiceFilter( field_name='partnership__years__funding_type', ) funding_program = filters.ModelChoiceFilter( field_name='partnership__years__funding_type__program', ) funding_source = filters.ModelChoiceFilter( field_name='partnership__years__funding_type__program__source', ) partnership_in = filters.CharFilter(method='filter_partnership_in') subtype = filters.CharFilter(field_name='partnership__years__subtype', ) partnership_ending_in = filters.CharFilter( method='filter_partnership_ending_in') partnership_valid_in = filters.CharFilter( method='filter_partnership_valid_in') partnership_not_valid_in = filters.CharFilter( method='filter_partnership_not_valid_in') partnership_with_no_agreements_in = filters.CharFilter( method='filter_partnership_with_no_agreements_in') partnership_date_type = filters.CharFilter( method='filter_partnership_date') # Noop filter, their logic is in filter_partnership_special_dates() partnership_date_from = filters.DateFilter(method=lambda qs, *_: qs) partnership_date_to = filters.DateFilter(method=lambda qs, *_: qs) comment = filters.CharFilter( field_name='partnership__comment', lookup_expr='icontains', ) is_public = filters.BooleanFilter( field_name='partnership__is_public', widget=CustomNullBooleanSelect(), ) class Meta: model = PartnershipPartnerRelation fields = [ 'ordering', 'partnership_type', 'partner_type', 'ucl_entity', 'education_level', 'years_entity', 'university_offer', 'partner_entity', 'erasmus_code', 'use_egracons', 'continent', 'country', 'city', 'partner_tags', 'education_field', 'is_sms', 'is_smp', 'is_sta', 'is_stt', 'is_smst', 'funding_type', 'funding_program', 'funding_source', 'supervisor', 'tags', 'partnership_in', 'partnership_ending_in', 'partnership_valid_in', 'partnership_not_valid_in', 'partnership_with_no_agreements_in', 'partnership_date_type', 'partnership_date_from', 'partnership_date_to', 'comment', 'is_public', ] @property def form(self): if not hasattr(self, '_form'): if self.is_bound: self._form = PartnershipFilterForm( self.data, user=self.request.user, prefix=self.form_prefix, ) else: self._form = PartnershipFilterForm( user=self.request.user, prefix=self.form_prefix, ) return self._form @staticmethod def filter_years_entity(queryset, name, value): if value: queryset = queryset.filter( Q(partnership__years__entities=value) | Q(partnership__years__entities__isnull=True)) return queryset def filter_ucl_entity(self, queryset, name, value): if value: if self.form.cleaned_data.get('ucl_entity_with_child', False): # Allow all children of entity too cte = EntityVersion.objects.with_parents(entity_id=value.pk) qs = cte.queryset().with_cte(cte).values('entity_id') queryset = queryset.filter(partnership__ucl_entity__in=qs) else: queryset = queryset.filter(partnership__ucl_entity=value) return queryset @staticmethod def filter_partner_tags(queryset, name, value): if value: queryset = queryset.filter( entity__organization__partner__tags__in=value) return queryset @staticmethod def filter_university_offer(queryset, name, value): if value: queryset = queryset.filter( Q(partnership__years__offers=value) | Q(partnership__years__offers__isnull=True)) return queryset @staticmethod def filter_partnership_in(queryset, name, value): if value: queryset = queryset.annotate(has_in=Exists( PartnershipAgreement.objects.filter( partnership=OuterRef('partnership_id'), start_academic_year__start_date__lte=value.start_date, end_academic_year__end_date__gte=value.end_date, ))).filter(has_in=True) return queryset @staticmethod def filter_partnership_ending_in(queryset, name, value): if value: queryset = (queryset.annotate(ending_date=Max( 'partnership__agreements__end_academic_year__end_date')). filter(ending_date=value.end_date)) return queryset @staticmethod def filter_partnership_valid_in(queryset, name, value): if value: queryset = queryset.annotate(has_valid=Exists( PartnershipAgreement.objects.filter( partnership=OuterRef('partnership_id'), status=AgreementStatus.VALIDATED.name, start_academic_year__start_date__lte=value.start_date, end_academic_year__end_date__gte=value.end_date, ))).filter(has_valid=True) return queryset @staticmethod def filter_partnership_not_valid_in(queryset, name, value): if value: queryset = queryset.annotate( not_valid_in_has_agreements=Exists( PartnershipAgreement.objects.filter( partnership=OuterRef('partnership_id'), ).filter( start_academic_year__start_date__lte=value.start_date, end_academic_year__end_date__gte=value.end_date, ), ), not_valid_in_has_valid_agreements=Exists( PartnershipAgreement.objects.filter( partnership=OuterRef('partnership_id'), ).filter( status=AgreementStatus.VALIDATED.name, start_academic_year__start_date__lte=value.start_date, end_academic_year__end_date__gte=value.end_date, ), )).filter( not_valid_in_has_agreements=True, not_valid_in_has_valid_agreements=False, ) return queryset @staticmethod def filter_partnership_with_no_agreements_in(queryset, name, value): if value: queryset = queryset.annotate( no_agreements_in_has_years=Exists( PartnershipYear.objects.filter( partnership=OuterRef('partnership_id'), academic_year=value, )), no_agreements_in_has_agreements=Exists( PartnershipAgreement.objects.filter( partnership=OuterRef('partnership_id'), start_academic_year__start_date__lte=value.start_date, end_academic_year__end_date__gte=value.end_date, )), ).filter( no_agreements_in_has_years=True, no_agreements_in_has_agreements=False, ) return queryset def filter_partnership_date(self, queryset, name, value): # Prevent filtering on partnership when agreement filter if isinstance(self, PartnershipAgreementAdminFilter ) and queryset.model == PartnershipPartnerRelation: return queryset date_from = self.form.cleaned_data['partnership_date_from'] date_to = self.form.cleaned_data.get('partnership_date_to') if value == DateFilterType.ONGOING.name: if not date_to: # start_date < filter_date < end_date return queryset.filter( partnership__start_date__lte=date_from, partnership__end_date__gte=date_from, ) # periods must intersect return queryset.filter( Q(partnership__start_date__lte=date_from, partnership__end_date__gte=date_from) | Q(partnership__start_date__lte=date_to, partnership__end_date__gte=date_to), ) elif value == DateFilterType.STOPPING.name: # filter_date_0 < end_date < filter_date_1 return queryset.filter( partnership__end_date__gte=date_from, partnership__end_date__lte=date_to, )
class IssueExtFieldFilter(filters.FilterSet): isOptional = django_filters.BooleanFilter(name='is_optional') class Meta: model = IssueExtField fields = ('name', 'default', 'isOptional', 'type')
class TraineeFilter(AMYFilterSet): search = django_filters.CharFilter( method=filter_trainees_by_trainee_name_or_email, label="Name or Email" ) all_persons = django_filters.BooleanFilter( label="Include all people, not only trainees", method=filter_all_persons, widget=widgets.CheckboxInput, ) homework = django_filters.BooleanFilter( label="Only trainees with unevaluated homework", widget=widgets.CheckboxInput, method=filter_trainees_by_unevaluated_homework_presence, ) training_request = django_filters.BooleanFilter( label="Is training request present?", method=filter_trainees_by_training_request_presence, ) is_instructor = django_filters.ChoiceFilter( label="Is Instructor?", method=filter_trainees_by_instructor_status, choices=[ ("", "Unknown"), ("all", "All instructor badges"), ("any", "Any instructor badge "), ("swc", "SWC instructor"), ("dc", "DC instructor"), ("lc", "LC instructor"), ("eligible", "No, but eligible to be certified"), ("no", "No instructor badge"), ], ) training = django_filters.ModelChoiceFilter( queryset=Event.objects.ttt(), method=filter_trainees_by_training, label="Training", widget=ModelSelect2Widget( data_view="ttt-event-lookup", attrs=SELECT2_SIDEBAR, ), ) order_by = NamesOrderingFilter( fields=( "last_login", "email", ), ) class Meta: model = Person fields = [ "search", "all_persons", "homework", "is_instructor", "training", ]
class DRYFilter(django_filters.FilterSet): name = django_filters.CharFilter(lookup_expr='icontains') score = django_filters.RangeFilter() rank = django_filters.NumberFilter() in_stock = django_filters.BooleanFilter() price = django_filters.RangeFilter()
class DeviceTypeFilterSet(BaseFilterSet, CustomFieldModelFilterSet, CreatedUpdatedFilterSet): q = django_filters.CharFilter( method='search', label='Search', ) manufacturer_id = django_filters.ModelMultipleChoiceFilter( queryset=Manufacturer.objects.all(), label='Manufacturer (ID)', ) manufacturer = django_filters.ModelMultipleChoiceFilter( field_name='manufacturer__slug', queryset=Manufacturer.objects.all(), to_field_name='slug', label='Manufacturer (slug)', ) console_ports = django_filters.BooleanFilter( method='_console_ports', label='Has console ports', ) console_server_ports = django_filters.BooleanFilter( method='_console_server_ports', label='Has console server ports', ) power_ports = django_filters.BooleanFilter( method='_power_ports', label='Has power ports', ) power_outlets = django_filters.BooleanFilter( method='_power_outlets', label='Has power outlets', ) interfaces = django_filters.BooleanFilter( method='_interfaces', label='Has interfaces', ) pass_through_ports = django_filters.BooleanFilter( method='_pass_through_ports', label='Has pass-through ports', ) device_bays = django_filters.BooleanFilter( method='_device_bays', label='Has device bays', ) tag = TagFilter() class Meta: model = DeviceType fields = [ 'id', 'model', 'slug', 'part_number', 'u_height', 'is_full_depth', 'subdevice_role', ] def search(self, queryset, name, value): if not value.strip(): return queryset return queryset.filter( Q(manufacturer__name__icontains=value) | Q(model__icontains=value) | Q(part_number__icontains=value) | Q(comments__icontains=value) ) def _console_ports(self, queryset, name, value): return queryset.exclude(consoleporttemplates__isnull=value) def _console_server_ports(self, queryset, name, value): return queryset.exclude(consoleserverporttemplates__isnull=value) def _power_ports(self, queryset, name, value): return queryset.exclude(powerporttemplates__isnull=value) def _power_outlets(self, queryset, name, value): return queryset.exclude(poweroutlettemplates__isnull=value) def _interfaces(self, queryset, name, value): return queryset.exclude(interfacetemplates__isnull=value) def _pass_through_ports(self, queryset, name, value): return queryset.exclude( frontporttemplates__isnull=value, rearporttemplates__isnull=value ) def _device_bays(self, queryset, name, value): return queryset.exclude(devicebaytemplates__isnull=value)
class EducationalOfferFilter(django_filters.FilterSet): eduoffer_institution = django_filters.ModelChoiceFilter( label=FieldEducationalOffer.INSTITUTION, queryset=Institution.objects.all(), widget=autocomplete.ModelSelect2(url='institution-autocomplete')) eduoffer_position_text = django_filters.CharFilter( label=FieldEducationalOffer.POSITION, lookup_expr='icontains', widget=forms.TextInput(attrs={'class': 'list__form--input'})) eduoffer_type = django_filters.ModelMultipleChoiceFilter( label=FieldEducationalOffer.TYPE, queryset=EducationalOfferType.objects.all(), widget=autocomplete.ModelSelect2Multiple( url='educationaloffertype-autocomplete')) eduoffer_mode = django_filters.ModelMultipleChoiceFilter( label=FieldEducationalOffer.MODE, queryset=EducationalOfferMode.objects.all(), widget=autocomplete.ModelSelect2Multiple( url='educationaloffermode-autocomplete')) eduoffer_city__region = django_filters.ModelChoiceFilter( label=FieldEducationalOffer.REGION, queryset=Region.objects.all(), widget=autocomplete.ModelSelect2(url='region-autocomplete')) eduoffer_city = django_filters.ModelChoiceFilter( label=FieldEducationalOffer.CITY, queryset=City.objects.all(), widget=autocomplete.ModelSelect2(url='city-autocomplete')) eduoffer_date_start = django_filters.DateFilter( label=FieldEducationalOffer.DATE_START, lookup_expr='gte', widget=forms.DateInput( attrs={'class': 'datepicker list__form--input'})) eduoffer_date_end = django_filters.DateFilter( label=FieldEducationalOffer.DATE_END, lookup_expr='lte', widget=forms.DateInput( attrs={'class': 'datepicker list__form--input'})) eduoffer_keywords = django_filters.ModelMultipleChoiceFilter( label=FieldEducationalOffer.KEYWORDS, queryset=Tag.objects.all(), widget=autocomplete.ModelSelect2Multiple(url='tag-autocomplete')) eduoffer_is_accepted = django_filters.BooleanFilter( label=FieldEducationalOffer.IS_ACCEPTED, widget=NullBooleanSelect(attrs={'class': 'select2'})) o = django_filters.OrderingFilter(fields=( ('eduoffer_is_promoted', 'eduoffer_is_promoted'), ('eduoffer_date_add', 'eduoffer_date_add'), ('eduoffer_position_text', 'eduoffer_position_text'), ('eduoffer_date_end', 'eduoffer_date_end'), ), ) strict = True class Meta: model = EducationalOffer form = EducationalOfferFilterForm fields = [ 'eduoffer_institution', 'eduoffer_position_text', 'eduoffer_type', 'eduoffer_mode', 'eduoffer_city__region', 'eduoffer_city', 'eduoffer_date_start', 'eduoffer_date_end', 'eduoffer_keywords', 'eduoffer_is_accepted' ]
class CableTerminationFilterSet(django_filters.FilterSet): cabled = django_filters.BooleanFilter( field_name='cable', lookup_expr='isnull', exclude=True )
class ResourceFilterSet(django_filters.FilterSet): def __init__(self, *args, **kwargs): self.user = kwargs.pop('user') super().__init__(*args, **kwargs) purpose = ParentCharFilter(field_name='purposes__id', lookup_expr='iexact') type = django_filters.Filter(field_name='type__id', lookup_expr='in', widget=django_filters.widgets.CSVWidget) people = django_filters.NumberFilter(field_name='people_capacity', lookup_expr='gte') need_manual_confirmation = django_filters.BooleanFilter( field_name='need_manual_confirmation', widget=DRFFilterBooleanWidget) is_favorite = django_filters.BooleanFilter(method='filter_is_favorite', widget=DRFFilterBooleanWidget) unit = django_filters.CharFilter(field_name='unit__id', lookup_expr='iexact') resource_group = django_filters.Filter( field_name='groups__identifier', lookup_expr='in', widget=django_filters.widgets.CSVWidget, distinct=True) equipment = django_filters.Filter( field_name='resource_equipment__equipment__id', lookup_expr='in', widget=django_filters.widgets.CSVWidget, distinct=True) available_between = django_filters.Filter( method='filter_available_between', widget=django_filters.widgets.CSVWidget) free_of_charge = django_filters.BooleanFilter( method='filter_free_of_charge', widget=DRFFilterBooleanWidget) municipality = django_filters.Filter( field_name='unit__municipality_id', lookup_expr='in', widget=django_filters.widgets.CSVWidget, distinct=True) order_by = ResourceOrderingFilter(fields=( ('name_fi', 'resource_name_fi'), ('name_en', 'resource_name_en'), ('name_sv', 'resource_name_sv'), ('unit__name_fi', 'unit_name_fi'), ('unit__name_en', 'unit_name_en'), ('unit__name_sv', 'unit_name_sv'), ('type__name_fi', 'type_name_fi'), ('type__name_en', 'type_name_en'), ('type__name_sv', 'type_name_sv'), ('people_capacity', 'people_capacity'), ('accessibility_priority', 'accessibility'), ), ) def filter_is_favorite(self, queryset, name, value): if not self.user.is_authenticated: if value: return queryset.none() else: return queryset if value: return queryset.filter(favorited_by=self.user) else: return queryset.exclude(favorited_by=self.user) def filter_free_of_charge(self, queryset, name, value): qs = Q(min_price__lte=0) | Q(min_price__isnull=True) if value: return queryset.filter(qs) else: return queryset.exclude(qs) def _deserialize_datetime(self, value): try: return arrow.get(value).datetime except ParserError: raise exceptions.ParseError( "'%s' must be a timestamp in ISO 8601 format" % value) def filter_available_between(self, queryset, name, value): if len(value) < 2 or len(value) > 3: raise exceptions.ParseError( 'available_between takes two or three comma-separated values.') available_start = self._deserialize_datetime(value[0]) available_end = self._deserialize_datetime(value[1]) if available_start.date() != available_end.date(): raise exceptions.ParseError( 'available_between timestamps must be on the same day.') overlapping_reservations = Reservation.objects.filter( resource__in=queryset, end__gt=available_start, begin__lt=available_end).current() if len(value) == 2: return self._filter_available_between_whole_range( queryset, overlapping_reservations, available_start, available_end) else: try: period = datetime.timedelta(minutes=int(value[2])) except ValueError: raise exceptions.ParseError( 'available_between period must be an integer.') return self._filter_available_between_with_period( queryset, overlapping_reservations, available_start, available_end, period) def _filter_available_between_whole_range(self, queryset, reservations, available_start, available_end): # exclude resources that have reservation(s) overlapping with the available_between range queryset = queryset.exclude(reservations__in=reservations) closed_resource_ids = { resource.id for resource in queryset if not self._is_resource_open( resource, available_start, available_end) } return queryset.exclude(id__in=closed_resource_ids) @staticmethod def _is_resource_open(resource, start, end): opening_hours = resource.get_opening_hours(start, end) if len(opening_hours) > 1: # range spans over multiple days, assume resources aren't open all night and skip the resource return False hours = next(iter(opening_hours.values()))[ 0] # assume there is only one hours obj per day if not hours['opens'] and not hours['closes']: return False start_too_early = hours['opens'] and start < hours['opens'] end_too_late = hours['closes'] and end > hours['closes'] if start_too_early or end_too_late: return False return True def _filter_available_between_with_period(self, queryset, reservations, available_start, available_end, period): reservations = reservations.order_by('begin').select_related( 'resource') reservations_by_resource = collections.defaultdict(list) for reservation in reservations: reservations_by_resource[reservation.resource_id].append( reservation) available_resources = set() hours_qs = ResourceDailyOpeningHours.objects.filter( open_between__overlap=(available_start, available_end, '[)')) # check the resources one by one to determine which ones have open slots for resource in queryset.prefetch_related(None).prefetch_related( Prefetch('opening_hours', queryset=hours_qs, to_attr='prefetched_opening_hours')): reservations = reservations_by_resource[resource.id] if self._is_resource_available(resource, available_start, available_end, reservations, period): available_resources.add(resource.id) return queryset.filter(id__in=available_resources) @staticmethod def _is_resource_available(resource, available_start, available_end, reservations, period): opening_hours = resource.get_opening_hours( available_start, available_end, resource.prefetched_opening_hours) hours = next(iter(opening_hours.values()))[ 0] # assume there is only one hours obj per day if not (hours['opens'] or hours['closes']): return False current = max( available_start, hours['opens']) if hours['opens'] is not None else available_start end = min( available_end, hours['closes']) if hours['closes'] is not None else available_end if current >= end: # the resource is already closed return False if not reservations: # the resource has no reservations, just check if the period fits in the resource's opening times if end - current >= period: return True return False # try to find an open slot between reservations and opening / closing times. # start from period start time or opening time depending on which one is earlier. for reservation in reservations: if reservation.end <= current: # this reservation is in the past continue if reservation.begin - current >= period: # found an open slot before the reservation currently being examined return True if reservation.end > end: # the reservation currently being examined ends after the period or closing time, # so no free slots return False # did not find an open slot before the reservation currently being examined, # proceed to next reservation current = reservation.end else: # all reservations checked and no free slot found, check if there is a free slot after the last # reservation if end - reservation.end >= period: return True return False class Meta: model = Resource fields = [ 'purpose', 'type', 'people', 'need_manual_confirmation', 'is_favorite', 'unit', 'available_between', 'min_price' ]
class EventDateFilter(django_filters.FilterSet): event_start__gte = django_filters.DateTimeFilter(field_name='event_start', lookup_expr='gte') event_start__lte = django_filters.DateTimeFilter(field_name='event_start', lookup_expr='lte') event_end__gte = django_filters.DateTimeFilter(field_name='event_end', lookup_expr='gte') event_end__lte = django_filters.DateTimeFilter(field_name='event_end', lookup_expr='lte') attendance_event__isnull = django_filters.BooleanFilter( field_name='attendance_event', lookup_expr='isnull') is_attendee = django_filters.BooleanFilter(field_name='attendance_event', method='filter_is_attendee') can_change = django_filters.BooleanFilter(method='filter_can_change') can_attend = django_filters.BooleanFilter(method='filter_can_attend') event_type = BaseNumberInFilter(field_name='event_type', lookup_expr='in') companies = BaseNumberInFilter(field_name='companies', lookup_expr='company__in') def filter_can_attend(self, queryset, name, value): """ Filter events based on if the user can attend said event. """ """ User cannot attend events if they are not logged in """ if not self.request.user.is_authenticated: return queryset.none() if value: events_with_attendance = queryset.filter( attendance_event__isnull=False) events_without_attendance = queryset.filter( attendance_event__isnull=True) user_attendable_event_pks = [] for event in events_with_attendance: response = event.attendance_event.rules_satisfied( self.request.user) can_attend = response.get('status', None) if can_attend: user_attendable_event_pks.append(event.id) user_attendable_events = events_with_attendance.filter( attendance_event__pk__in=user_attendable_event_pks) all_available_events = user_attendable_events | events_without_attendance return all_available_events return queryset.all() def filter_is_attendee(self, queryset, name, value): """ Filter events based on if a user is attending them or not. """ """ User cannot attend events if they are not logged in """ if not self.request.user.is_authenticated: return queryset.none() user_attendees = Attendee.objects.filter(user=self.request.user) attending_events = [attendee.event.pk for attendee in user_attendees] if value: return queryset.filter(pk__in=attending_events) return queryset.all() def filter_can_change(self, queryset, name, value): """ Filter events based on if the user has permission to change them """ """ If filter is set to False, don't filter """ if not value: return queryset user = self.request.user """ User cannot attend events if they are not logged in """ if not user.is_authenticated: return queryset.none() """ Don't filter on this field if user is a superuser """ if user.is_superuser: return queryset allowed_events = get_objects_for_user(user, 'events.change_event', accept_global_perms=False, klass=queryset) return allowed_events class Meta: model = Event fields = ('event_start', 'event_end', 'event_type', 'is_attendee')
class SnailMailTaskFilterSet(TaskFilterSet): """Allows snail mail tasks to be filtered by category, as well as the presence of a tracking number or an agency note.""" category = django_filters.ChoiceFilter(choices=[('', 'All')] + SNAIL_MAIL_CATEGORIES) has_address = django_filters.ChoiceFilter( method='filter_has_address', label='Has address', choices=BOOLEAN_CHOICES, ) has_attachments = django_filters.ChoiceFilter( method='filter_has_attachments', label='Has attachments', choices=BOOLEAN_CHOICES, ) has_tracking_number = django_filters.ChoiceFilter( method='filter_has_tracking_number', label='Has tracking number', choices=BOOLEAN_CHOICES, ) has_agency_notes = django_filters.ChoiceFilter( method='filter_has_agency_notes', label='Has agency notes', choices=BOOLEAN_CHOICES, ) resolved = django_filters.BooleanFilter(label='Show Resolved', widget=forms.CheckboxInput()) resolved_by = django_filters.ModelMultipleChoiceFilter( queryset=User.objects.all(), widget=autocomplete_light.MultipleChoiceWidget('UserTaskAutocomplete')) def blank_choice(self, queryset, name, value): """Check if the value is blank""" if value == 'True': return queryset.exclude(**{name: ''}) elif value == 'False': return queryset.filter(**{name: ''}) return queryset def filter_has_address(self, queryset, name, value): """Check if the foia has an address.""" #pylint: disable=unused-argument if value == 'True': return queryset.exclude(communication__foia__address=None) else: return queryset.filter(communication__foia__address=None) def filter_has_attachments(self, queryset, name, value): """Check if the communication has attachments.""" #pylint: disable=unused-argument if value == 'True': return queryset.exclude(communication__files=None) else: return queryset.filter(communication__files=None) def filter_has_tracking_number(self, queryset, name, value): """Check if the foia has a tracking number.""" #pylint: disable=unused-argument if value == 'True': return queryset.exclude(communication__foia__tracking_ids=None) else: return queryset.filter(communication__foia__tracking_ids=None) def filter_has_agency_notes(self, queryset, name, value): """Check if the agency has notes.""" #pylint: disable=unused-argument return self.blank_choice(queryset, 'communication__foia__agency__notes', value) class Meta: model = SnailMailTask fields = [ 'category', 'has_address', 'has_attachments', 'has_tracking_number', 'has_agency_notes', 'resolved', 'resolved_by', ]
class PerformanceAlertSummaryFilter(django_filters.FilterSet): id = django_filters.NumberFilter(field_name='id') status = django_filters.NumberFilter(field_name='status') framework = django_filters.NumberFilter(field_name='framework') repository = django_filters.NumberFilter(field_name='repository') alerts__series_signature = django_filters.NumberFilter( field_name='alerts__series_signature') filter_text = django_filters.CharFilter(method='_filter_text') hide_improvements = django_filters.BooleanFilter( method='_hide_improvements') hide_related_and_invalid = django_filters.BooleanFilter( method='_hide_related_and_invalid') with_assignee = django_filters.CharFilter(method='_with_assignee') def _filter_text(self, queryset, name, value): sep = Value(' ') words = value.split(' ') contains_all_words = [Q(full_name__contains=word) for word in words] # Django's distinct(*fields) isn't supported for MySQL # https://code.djangoproject.com/ticket/17974 filtered_summaries = (queryset.annotate(full_name=Concat( 'alerts__series_signature__suite', sep, 'alerts__series_signature__test', sep, 'alerts__series_signature__platform__platform', sep, 'alerts__series_signature__extra_options', sep, 'bug_number', sep, 'push__revision', output_field=CharField(), )).filter(*contains_all_words).values('id').distinct()) return queryset.filter(id__in=Subquery(filtered_summaries)) def _hide_improvements(self, queryset, name, value): return queryset.annotate( total_regressions=Count('alerts__is_regression')).filter( alerts__is_regression=True, total_regressions__gte=1) def _hide_related_and_invalid(self, queryset, name, value): return queryset.exclude(status__in=[ PerformanceAlertSummary.DOWNSTREAM, PerformanceAlertSummary.REASSIGNED, PerformanceAlertSummary.INVALID, ]) def _with_assignee(self, queryset, name, value): return queryset.filter(assignee__username=value) class Meta: model = PerformanceAlertSummary fields = [ 'id', 'status', 'framework', 'repository', 'alerts__series_signature', 'filter_text', 'hide_improvements', 'hide_related_and_invalid', 'with_assignee', ]
class DeviceFilter(CustomFieldFilterSet, django_filters.FilterSet): q = django_filters.MethodFilter( action='search', label='Search', ) site_id = django_filters.ModelMultipleChoiceFilter( name='rack__site', queryset=Site.objects.all(), label='Site (ID)', ) site = django_filters.ModelMultipleChoiceFilter( name='rack__site', queryset=Site.objects.all(), to_field_name='slug', label='Site name (slug)', ) rack_group_id = django_filters.ModelMultipleChoiceFilter( name='rack__group', queryset=RackGroup.objects.all(), label='Rack group (ID)', ) rack_id = django_filters.ModelMultipleChoiceFilter( name='rack', queryset=Rack.objects.all(), label='Rack (ID)', ) role_id = django_filters.ModelMultipleChoiceFilter( name='device_role', queryset=DeviceRole.objects.all(), label='Role (ID)', ) role = django_filters.ModelMultipleChoiceFilter( name='device_role', queryset=DeviceRole.objects.all(), to_field_name='slug', label='Role (slug)', ) tenant_id = NullableModelMultipleChoiceFilter( name='tenant', queryset=Tenant.objects.all(), label='Tenant (ID)', ) tenant = NullableModelMultipleChoiceFilter( name='tenant', queryset=Tenant.objects.all(), to_field_name='slug', label='Tenant (slug)', ) device_type_id = django_filters.ModelMultipleChoiceFilter( name='device_type', queryset=DeviceType.objects.all(), label='Device type (ID)', ) manufacturer_id = django_filters.ModelMultipleChoiceFilter( name='device_type__manufacturer', queryset=Manufacturer.objects.all(), label='Manufacturer (ID)', ) manufacturer = django_filters.ModelMultipleChoiceFilter( name='device_type__manufacturer', queryset=Manufacturer.objects.all(), to_field_name='slug', label='Manufacturer (slug)', ) model = django_filters.ModelMultipleChoiceFilter( name='device_type', queryset=DeviceType.objects.all(), to_field_name='slug', label='Device model (slug)', ) platform_id = NullableModelMultipleChoiceFilter( name='platform', queryset=Platform.objects.all(), label='Platform (ID)', ) platform = NullableModelMultipleChoiceFilter( name='platform', queryset=Platform.objects.all(), to_field_name='slug', label='Platform (slug)', ) status = django_filters.BooleanFilter( name='status', label='Status', ) is_console_server = django_filters.BooleanFilter( name='device_type__is_console_server', label='Is a console server', ) is_pdu = django_filters.BooleanFilter( name='device_type__is_pdu', label='Is a PDU', ) is_network_device = django_filters.BooleanFilter( name='device_type__is_network_device', label='Is a network device', ) class Meta: model = Device fields = ['q', 'name', 'serial', 'asset_tag', 'site_id', 'site', 'rack_id', 'role_id', 'role', 'device_type_id', 'manufacturer_id', 'manufacturer', 'model', 'platform_id', 'platform', 'status', 'is_console_server', 'is_pdu', 'is_network_device'] def search(self, queryset, value): return queryset.filter( Q(name__icontains=value) | Q(serial__icontains=value.strip()) | Q(modules__serial__icontains=value.strip()) | Q(asset_tag=value.strip()) | Q(comments__icontains=value) ).distinct()
class ExperimentFilterset(filters.FilterSet): search = filters.CharFilter( method="filter_search", widget=SearchWidget( attrs={"class": "form-control", "placeholder": "Search Experiments"} ), ) type = filters.MultipleChoiceFilter( choices=Experiment.TYPE_CHOICES, conjoined=False, widget=forms.SelectMultiple(attrs={"class": "form-control"}), ) status = filters.ChoiceFilter( empty_label="All Statuses", choices=Experiment.STATUS_CHOICES, widget=forms.Select(attrs={"class": "form-control"}), ) firefox_channel = filters.ChoiceFilter( empty_label="All Channels", choices=Experiment.CHANNEL_CHOICES[1:], widget=forms.Select(attrs={"class": "form-control"}), ) firefox_version = filters.ChoiceFilter( empty_label="All Versions", choices=Experiment.VERSION_CHOICES[1:], widget=forms.Select(attrs={"class": "form-control"}), method="version_filter", ) owner = filters.ModelChoiceFilter( empty_label="All Owners", queryset=get_user_model().objects.all().order_by("email"), widget=forms.Select(attrs={"class": "form-control"}), ) analysis_owner = filters.ModelChoiceFilter( empty_label="All Data Scientists", queryset=get_user_model().objects.all().order_by("email"), widget=forms.Select(attrs={"class": "form-control"}), ) archived = filters.BooleanFilter( label="Show archived experiments", widget=forms.CheckboxInput(), method="archived_filter", ) experiment_date_field = filters.ChoiceFilter( empty_label="No Date Restriction", choices=[ (Experiment.EXPERIMENT_STARTS, "Experiment Starts"), (Experiment.EXPERIMENT_PAUSES, "Experiment Pauses"), (Experiment.EXPERIMENT_ENDS, "Experiment Ends"), ], widget=forms.Select(attrs={"class": "form-control"}), method="experiment_date_field_filter", ) date_range = filters.DateFromToRangeFilter( method="date_range_filter", widget=DateRangeWidget(attrs={"type": "date", "class": "form-control"}), ) in_qa = filters.BooleanFilter( label="Show only experiments in QA", widget=forms.CheckboxInput(), method="in_qa_filter", ) surveys = filters.BooleanFilter( label="Show experiments with surveys", widget=forms.CheckboxInput(), method="surveys_filter", ) subscribed = filters.BooleanFilter( label="Show subscribed experiments", widget=forms.CheckboxInput(), method="subscribed_filter", ) longrunning = filters.BooleanFilter( label="Show long-running experiments", widget=forms.CheckboxInput(), method="longrunning_filter", ) is_paused = filters.BooleanFilter( label="Show enrollment complete experiments", widget=forms.CheckboxInput(), method="is_paused_filter", ) class Meta: model = Experiment fields = ( "search", "type", "status", "firefox_channel", "firefox_version", "owner", "analysis_owner", "in_qa", "surveys", "archived", "subscribed", "longrunning", "is_paused", ) def filter_search(self, queryset, name, value): vector = SearchVector( "name", "short_description", "owner__email", "analysis_owner__email", "slug", "related_work", "addon_experiment_id", "pref_key", "public_name", "public_description", "objectives", "analysis", "engineering_owner", "bugzilla_id", "normandy_slug", "data_science_bugzilla_url", "feature_bugzilla_url", ) query = SearchQuery(value) return ( queryset.annotate(rank=SearchRank(vector, query), search=vector) .filter(search=value) .order_by("-rank") ) def archived_filter(self, queryset, name, value): if not value: return queryset.exclude(archived=True) return queryset def experiment_date_field_filter(self, queryset, name, value): # this custom method isn't doing anything. There has to # be a custom method to be able to display the select # filter that controls which date range we show return queryset def version_filter(self, queryset, name, value): return queryset.filter( Q(firefox_min_version__lte=value, firefox_max_version__gte=value) | Q(firefox_min_version=value) ) def date_range_filter(self, queryset, name, value): date_type = self.form.cleaned_data["experiment_date_field"] experiment_date_field = { Experiment.EXPERIMENT_STARTS: "start_date", Experiment.EXPERIMENT_PAUSES: "enrollment_end_date", Experiment.EXPERIMENT_ENDS: "end_date", }[date_type] results = [] for experiment in queryset.all(): date = getattr(experiment, experiment_date_field) # enrollment end dates are optional, so there won't always # be a pause date for an experiment if date: if value.start and date < value.start.date(): continue if value.stop and date > value.stop.date(): continue results.append(experiment.id) return queryset.filter(pk__in=results) def in_qa_filter(self, queryset, name, value): if value: return queryset.filter(review_qa_requested=True, review_qa=False) return queryset def surveys_filter(self, queryset, name, value): if value: return queryset.filter(survey_required=True) return queryset def subscribed_filter(self, queryset, name, value): if value: return queryset.filter(subscribers__in=[self.request.user.id]) return queryset def longrunning_filter(self, queryset, name, value): if value: return ( queryset.exclude(firefox_max_version__exact="") .annotate( firefox_min_int=Cast( Func( F("firefox_min_version"), Value(ExperimentConstants.VERSION_REGEX.pattern), function="substring", ), IntegerField(), ), firefox_max_int=Cast( Func( F("firefox_max_version"), Value(ExperimentConstants.VERSION_REGEX.pattern), function="substring", ), IntegerField(), ), version_count=F("firefox_max_int") - F("firefox_min_int"), ) .filter(version_count__gte=3) ) return queryset def is_paused_filter(self, queryset, name, value): if value: return queryset.filter(is_paused=True, status=Experiment.STATUS_LIVE) return queryset def get_type_display_value(self): return ", ".join( [ dict(Experiment.TYPE_CHOICES)[type].replace(" Experiment", "") for type in self.data.getlist("type") ] ) def get_owner_display_value(self): user_id = self.data.get("owner") if user_id is not None: return str(get_user_model().objects.get(id=user_id)) def get_display_start_date_info(self): experiment_date_field = self.data.get("experiment_date_field") date_after = self.data.get("date_range_after") date_before = self.data.get("date_range_before") if date_after and date_before: return f"{experiment_date_field} between {date_after} and {date_before}" elif date_after and date_before == "": return f"{experiment_date_field} after {date_after}" elif date_after == "" and date_before: return f"{experiment_date_field} before {date_before}" else: return ""
class NormaFilterSet(django_filters.FilterSet): ano = django_filters.ChoiceFilter(required=False, label='Ano', choices=choice_anos_com_normas) ementa = django_filters.CharFilter( label=_('Pesquisar expressões na ementa'), help_text=_( '"Para busca no conteúdo das normas, use a Pesquisa Textual"'), method='filter_ementa') numero = django_filters.CharFilter(label=_('Número'), method='filter_numero') apelido = django_filters.CharFilter(lookup_expr='icontains', label=_('Apelido')) indexacao = django_filters.CharFilter(lookup_expr='icontains', label=_('Indexação')) assuntos = django_filters.ModelChoiceFilter( queryset=AssuntoNorma.objects.all()) vigencia = django_filters.BooleanFilter(label='Vigência', method='filter_vigencia') signeds = django_filters.ChoiceFilter(required=False, choices=CHOICE_SIGNEDS, label=_('Com Assinatura Digital?'), method='filter_signeds') o = NormaPesquisaOrderingFilter(help_text='') class Meta(FilterOverridesMetaMixin): model = NormaJuridica fields = [ 'tipo', 'numero', 'ano', 'data', 'data_vigencia', 'data_publicacao', 'ementa', 'assuntos', 'apelido' ] def __init__(self, *args, **kwargs): super(NormaFilterSet, self).__init__(*args, **kwargs) row1 = to_row([('tipo', 4), ('numero', 4), ('ano', 4)]) row2 = to_row([('ementa', 6), ('assuntos', 6)]) row3 = to_row([('data', 6), ('data_publicacao', 6)]) #row4 = to_row([('data_vigencia', 10), ('vigencia', 2)]) row5 = to_row([('o', 4), ('signeds', 4), ('apelido', 4)]) self.form.helper = SaplFormHelper() self.form.helper.form_method = 'GET' self.form.helper.layout = Layout( Fieldset( _(''' Pesquisa de Norma<br> <small> <strong class="text-red">TODOS OS CAMPOS SÃO OPCIONAIS!</strong> </small> '''), row1, row2, row3, row5, # row4, form_actions(label='Pesquisar'))) def filter_ementa(self, queryset, name, value): texto = value.split() q = Q() for t in texto: q &= Q(ementa__icontains=t) return queryset.filter(q) def filter_signeds(self, queryset, name, value): q = Q() if not value: return queryset if value == '1': q &= Q(metadata__signs__texto_integral__0__isnull=False) else: q &= (Q(metadata__signs__texto_integral__isnull=True) | Q(metadata__signs__texto_integral__len=0)) return queryset.filter(q) def filter_vigencia(self, queryset, name, value): data_atual = timezone.now() if value: queryset = queryset.filter( Q(data_vigencia__lt=data_atual) | Q(data_vigencia__isnull=True)) else: queryset = queryset.filter(data_vigencia__gt=data_atual) return queryset def filter_numero(self, qs, name, value): value = value.replace('.', '') value = value.replace(',', '') if len(value) > 2: qs = qs.filter(numero__icontains=value) else: qs = qs.filter(numero=value) return qs
class DeviceFilter(CustomFieldFilterSet, django_filters.FilterSet): id__in = NumericInFilter(name='id', lookup_expr='in') q = django_filters.CharFilter( method='search', label='Search', ) manufacturer_id = django_filters.ModelMultipleChoiceFilter( name='device_type__manufacturer', queryset=Manufacturer.objects.all(), label='Manufacturer (ID)', ) manufacturer = django_filters.ModelMultipleChoiceFilter( name='device_type__manufacturer__slug', queryset=Manufacturer.objects.all(), to_field_name='slug', label='Manufacturer (slug)', ) device_type_id = django_filters.ModelMultipleChoiceFilter( queryset=DeviceType.objects.all(), label='Device type (ID)', ) role_id = django_filters.ModelMultipleChoiceFilter( name='device_role_id', queryset=DeviceRole.objects.all(), label='Role (ID)', ) role = django_filters.ModelMultipleChoiceFilter( name='device_role__slug', queryset=DeviceRole.objects.all(), to_field_name='slug', label='Role (slug)', ) tenant_id = NullableModelMultipleChoiceFilter( queryset=Tenant.objects.all(), label='Tenant (ID)', ) tenant = NullableModelMultipleChoiceFilter( name='tenant', queryset=Tenant.objects.all(), to_field_name='slug', label='Tenant (slug)', ) platform_id = NullableModelMultipleChoiceFilter( queryset=Platform.objects.all(), label='Platform (ID)', ) platform = NullableModelMultipleChoiceFilter( name='platform', queryset=Platform.objects.all(), to_field_name='slug', label='Platform (slug)', ) name = NullableCharFieldFilter() asset_tag = NullableCharFieldFilter() site_id = django_filters.ModelMultipleChoiceFilter( queryset=Site.objects.all(), label='Site (ID)', ) site = django_filters.ModelMultipleChoiceFilter( name='site__slug', queryset=Site.objects.all(), to_field_name='slug', label='Site name (slug)', ) rack_group_id = django_filters.ModelMultipleChoiceFilter( name='rack__group', queryset=RackGroup.objects.all(), label='Rack group (ID)', ) rack_id = NullableModelMultipleChoiceFilter( name='rack', queryset=Rack.objects.all(), label='Rack (ID)', ) model = django_filters.ModelMultipleChoiceFilter( name='device_type__slug', queryset=DeviceType.objects.all(), to_field_name='slug', label='Device model (slug)', ) status = django_filters.MultipleChoiceFilter(choices=STATUS_CHOICES) is_full_depth = django_filters.BooleanFilter( name='device_type__is_full_depth', label='Is full depth', ) is_console_server = django_filters.BooleanFilter( name='device_type__is_console_server', label='Is a console server', ) is_pdu = django_filters.BooleanFilter( name='device_type__is_pdu', label='Is a PDU', ) is_network_device = django_filters.BooleanFilter( name='device_type__is_network_device', label='Is a network device', ) mac_address = django_filters.CharFilter( method='_mac_address', label='MAC address', ) has_primary_ip = django_filters.BooleanFilter( method='_has_primary_ip', label='Has a primary IP', ) class Meta: model = Device fields = ['serial'] def search(self, queryset, name, value): if not value.strip(): return queryset qs_filter = (Q(name__icontains=value) | Q(serial__icontains=value.strip()) | Q(inventory_items__serial__icontains=value.strip()) | Q(asset_tag=value.strip()) | Q(comments__icontains=value)) # If the query value looks like a MAC address, search interfaces as well. try: mac = EUI(value.strip()) qs_filter |= Q(interfaces__mac_address=mac) except AddrFormatError: pass return queryset.filter(qs_filter).distinct() def _mac_address(self, queryset, name, value): value = value.strip() if not value: return queryset try: mac = EUI(value.strip()) return queryset.filter(interfaces__mac_address=mac).distinct() except AddrFormatError: return queryset.none() def _has_primary_ip(self, queryset, name, value): if value: return queryset.filter( Q(primary_ip4__isnull=False) | Q(primary_ip6__isnull=False)) else: return queryset.exclude( Q(primary_ip4__isnull=False) | Q(primary_ip6__isnull=False))
class InterfaceFilter(django_filters.FilterSet): """ Not using DeviceComponentFilterSet for Interfaces because we need to check for VirtualChassis membership. """ q = django_filters.CharFilter( method='search', label='Search', ) device = django_filters.CharFilter( method='filter_device', field_name='name', label='Device', ) device_id = MultiValueNumberFilter( method='filter_device_id', field_name='pk', label='Device (ID)', ) cabled = django_filters.BooleanFilter(field_name='cable', lookup_expr='isnull', exclude=True) kind = django_filters.CharFilter( method='filter_kind', label='Kind of interface', ) lag_id = django_filters.ModelMultipleChoiceFilter( field_name='lag', queryset=Interface.objects.all(), label='LAG interface (ID)', ) mac_address = MultiValueMACAddressFilter() tag = TagFilter() vlan_id = django_filters.CharFilter(method='filter_vlan_id', label='Assigned VLAN') vlan = django_filters.CharFilter(method='filter_vlan', label='Assigned VID') type = django_filters.MultipleChoiceFilter(choices=IFACE_TYPE_CHOICES, null_value=None) class Meta: model = Interface fields = [ 'id', 'name', 'connection_status', 'type', 'enabled', 'mtu', 'mgmt_only', 'mode', 'description' ] def search(self, queryset, name, value): if not value.strip(): return queryset return queryset.filter( Q(name__icontains=value) | Q(description__icontains=value)).distinct() def filter_device(self, queryset, name, value): try: device = Device.objects.get(**{name: value}) vc_interface_ids = device.vc_interfaces.values_list('id', flat=True) return queryset.filter(pk__in=vc_interface_ids) except Device.DoesNotExist: return queryset.none() def filter_device_id(self, queryset, name, id_list): # Include interfaces belonging to peer virtual chassis members vc_interface_ids = [] try: devices = Device.objects.filter(pk__in=id_list) for device in devices: vc_interface_ids += device.vc_interfaces.values_list('id', flat=True) return queryset.filter(pk__in=vc_interface_ids) except Device.DoesNotExist: return queryset.none() def filter_vlan_id(self, queryset, name, value): value = value.strip() if not value: return queryset return queryset.filter( Q(untagged_vlan_id=value) | Q(tagged_vlans=value)) def filter_vlan(self, queryset, name, value): value = value.strip() if not value: return queryset return queryset.filter( Q(untagged_vlan_id__vid=value) | Q(tagged_vlans__vid=value)) def filter_kind(self, queryset, name, value): value = value.strip().lower() return { 'physical': queryset.exclude(type__in=NONCONNECTABLE_IFACE_TYPES), 'virtual': queryset.filter(type__in=VIRTUAL_IFACE_TYPES), 'wireless': queryset.filter(type__in=WIRELESS_IFACE_TYPES), }.get(value, queryset.none())
class IPAddressFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet): q = django_filters.CharFilter( method='search', label='Search', ) family = django_filters.NumberFilter(field_name='address', lookup_expr='family') parent = django_filters.CharFilter( method='search_by_parent', label='Parent prefix', ) address = MultiValueCharFilter( method='filter_address', label='Address', ) mask_length = django_filters.NumberFilter( method='filter_mask_length', label='Mask length', ) vrf_id = django_filters.ModelMultipleChoiceFilter( queryset=VRF.objects.all(), label='VRF', ) vrf = django_filters.ModelMultipleChoiceFilter( field_name='vrf__rd', queryset=VRF.objects.all(), to_field_name='rd', label='VRF (RD)', ) device = MultiValueCharFilter( method='filter_device', field_name='name', label='Device (name)', ) device_id = MultiValueNumberFilter( method='filter_device', field_name='pk', label='Device (ID)', ) virtual_machine_id = django_filters.ModelMultipleChoiceFilter( field_name='interface__virtual_machine', queryset=VirtualMachine.objects.all(), label='Virtual machine (ID)', ) virtual_machine = django_filters.ModelMultipleChoiceFilter( field_name='interface__virtual_machine__name', queryset=VirtualMachine.objects.all(), to_field_name='name', label='Virtual machine (name)', ) interface = django_filters.ModelMultipleChoiceFilter( field_name='interface__name', queryset=Interface.objects.all(), to_field_name='name', label='Interface (ID)', ) interface_id = django_filters.ModelMultipleChoiceFilter( queryset=Interface.objects.all(), label='Interface (ID)', ) assigned_to_interface = django_filters.BooleanFilter( method='_assigned_to_interface', label='Is assigned to an interface', ) status = django_filters.MultipleChoiceFilter( choices=IPAddressStatusChoices, null_value=None) role = django_filters.MultipleChoiceFilter(choices=IPAddressRoleChoices) tag = TagFilter() class Meta: model = IPAddress fields = ['id', 'dns_name'] def search(self, queryset, name, value): if not value.strip(): return queryset qs_filter = (Q(dns_name__icontains=value) | Q(description__icontains=value) | Q(address__istartswith=value)) return queryset.filter(qs_filter) def search_by_parent(self, queryset, name, value): value = value.strip() if not value: return queryset try: query = str(netaddr.IPNetwork(value.strip()).cidr) return queryset.filter(address__net_host_contained=query) except (AddrFormatError, ValueError): return queryset.none() def filter_address(self, queryset, name, value): try: return queryset.filter(address__net_in=value) except ValidationError: return queryset.none() def filter_mask_length(self, queryset, name, value): if not value: return queryset return queryset.filter(address__net_mask_length=value) def filter_device(self, queryset, name, value): try: devices = Device.objects.prefetch_related('device_type').filter( **{'{}__in'.format(name): value}) vc_interface_ids = [] for device in devices: vc_interface_ids.extend( [i['id'] for i in device.vc_interfaces.values('id')]) return queryset.filter(interface_id__in=vc_interface_ids) except Device.DoesNotExist: return queryset.none() def _assigned_to_interface(self, queryset, name, value): return queryset.exclude(interface__isnull=value)
class DomainFilter(django_filters.FilterSet): """ Filter :model:`shepherd.Domain` model for searching. **Fields** ``name`` Case insensitive search of the name field contents ``categorization`` Case insensitive search of the categorization field ``health_status`` Checkbox choice filter using :model:`shepherd.HealthStatus` ``domain_status`` Checkbox choice filter using :model:`shepherd.DomainStatus` ``exclude_expired`` Checkbox to exclude expired domains from search results """ name = django_filters.CharFilter( lookup_expr="icontains", label="Domain Name Contains", widget=TextInput(attrs={ "placeholder": "Domain Name", "autocomplete": "off" }), ) categorization = django_filters.CharFilter( lookup_expr="icontains", label="Categories Contain", widget=TextInput(attrs={ "placeholder": "Category", "autocomplete": "off" }), ) health_status = django_filters.ModelMultipleChoiceFilter( queryset=HealthStatus.objects.all(), widget=forms.CheckboxSelectMultiple, label="", ) domain_status = django_filters.ModelMultipleChoiceFilter( queryset=DomainStatus.objects.all(), widget=forms.CheckboxSelectMultiple, label="", ) exclude_expired = django_filters.BooleanFilter( label="Filter Expired", method="filter_expired", widget=forms.CheckboxInput, ) class Meta: model = Domain fields = ["name", "categorization", "health_status", "domain_status"] def filter_expired(self, queryset, name, value): """ Choose to include or exclude expired domains in search results. """ if value: # return queryset.filter(Q(expiration__lt=date.today()) & Q(auto_renew=False)) return queryset.filter( Q(expiration__gte=date.today()) | Q(auto_renew=True)) return queryset def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.helper = FormHelper() self.helper.form_method = "get" self.helper.form_class = "newitem" self.helper.form_show_labels = True # Layout the form for Bootstrap self.helper.layout = Layout( Row( Column( PrependedText("name", '<i class="fas fa-filter"></i>'), css_class="col-md-6", ), Column( PrependedText("categorization", '<i class="fas fa-filter"></i>'), css_class="col-md-6", ), css_class="form-row", ), Accordion( AccordionGroup("Domain Status", InlineCheckboxes("domain_status"), SwitchToggle("exclude_expired")), AccordionGroup("Health Status", InlineCheckboxes("health_status")), ), ButtonHolder( HTML(""" <a class="btn btn-info col-md-2" role="button" href="{% url 'shepherd:domain_create' %}">Create</a> """), Submit("submit_btn", "Filter", css_class="btn btn-primary col-md-2"), HTML(""" <a class="btn btn-outline-secondary col-md-2" role="button" href="{% url 'shepherd:domains' %}">Reset</a> """), ), )