def filter_factory(ds_name, model): model_name = ds_name.upper() + 'GenericFilter' ds = DataSet.objects.get(name=ds_name) name_field = ds.name_field or 'UNKNOWN' geometry_field = ds.geometry_field or 'UNKNOWN' geometry_type = ds.geometry_type or 'UNKNOWN' fields = [name_field, geometry_field] location_filter_name = ':'.join([geometry_field, geometry_type]) location = filters.CharFilter(field_name=location_filter_name, method="location_filter") name = filters.CharFilter(field_name=name_field, method="name_filter") # Create datetime filters date_filters = dict() for field in model._meta.fields: if isinstance(field, models.DateField): date_filters[field.name] = filters.DateTimeFilter() date_filters[f'{field.name}__lte'] = filters.DateTimeFilter( field_name=field.name, method='date__lte') date_filters[f'{field.name}__gte'] = filters.DateTimeFilter( field_name=field.name, method='date__gte') fields += date_filters.keys() new_meta_attrs = {'model': model, 'fields': fields, } new_meta = type('Meta', (object,), new_meta_attrs) new_attrs = { '__module__': 'various_small_datasets.gen_api.filters', 'Meta': new_meta, geometry_field: location, name_field: name, **date_filters } return type(model_name, (GenericFilter,), new_attrs)
class FreightsFilterSet(FilterSet): channel = filters.ModelChoiceFilter(queryset=DataDictsValue.objects.all(), help_text='货运渠道') trans_company = filters.ModelChoiceFilter(queryset=DataDictsValue.objects.all(), help_text='货运公司') freight_status = filters.ChoiceFilter(choices=settings.FREIGHT_STATUS_CHOICE, help_text='货运状态') pack_time_start = filters.DateTimeFilter(field_name='pack_time', lookup_expr='gte', help_text='查询运单(起始打包时间)') pack_time_end = filters.DateTimeFilter(field_name='pack_time', lookup_expr='lte', help_text='查询运单(结束打包时间)') class Meta: model = FreightsInfo fields = []
class OrdersFilterSet(FilterSet): customer__salesman = filters.ModelChoiceFilter(queryset=UsersInfo.objects.all(), help_text='业务员') customer__service = filters.ModelChoiceFilter(queryset=UsersInfo.objects.all(), help_text='客服专员') operators = filters.ModelChoiceFilter(queryset=UsersInfo.objects.all(), help_text='操作员') order_status = filters.ChoiceFilter(choices=settings.ORDER_STATUS_CHOICE, help_text='订单状态') channel = filters.ModelChoiceFilter(queryset=DataDictsValue.objects.all(), help_text='服务渠道') order_time_start = filters.DateTimeFilter(field_name='order_time', lookup_expr='order_time__gte', help_text='订单时间') order_time_end = filters.DateTimeFilter(field_name='order_time', lookup_expr='order_time_lte', help_text='订单时间') class Meta: model = OrdersInfo fields = []
class KilogramFilter(FilterSet): id = filters.CharFilter() in_bbox = filters.CharFilter(method='in_bbox_filter', label='bbox') detailed = filters.BooleanFilter(method='detailed_filter', label='detailed view') weigh_at_gt = filters.DateTimeFilter('weigh_at', lookup_expr='gt') weigh_at_lt = filters.DateTimeFilter('weigh_at', lookup_expr='lt') location = filters.CharFilter(method="locatie_filter", label='x,y,r') fractie = filters.ChoiceFilter(choices=settings.WASTE_CHOICES, label='waste name') # stadsdeel = filters.ChoiceFilter(choices=STADSDELEN) # buurt_code = filters.ChoiceFilter(choices=buurt_choices) class Meta(object): model = KilogramWeighMeasurement fields = ( "id", "seq_id", "fractie", "weigh_at", "weigh_at_gt", "weigh_at_lt", "stadsdeel", "buurt_code", "site_id", "first_weight", "second_weight", "net_weight", "in_bbox", "location", "detailed", "valid", ) def in_bbox_filter(self, qs, name, value): bbox_values, err = bbox.valid_bbox(value) lat1, lon1, lat2, lon2 = bbox_values poly_bbox = Polygon.from_bbox((lon1, lat1, lon2, lat2)) if err: raise ValidationError(f"bbox invalid {err}:{bbox_values}") return qs.filter(geometrie__bboverlaps=(poly_bbox)) def locatie_filter(self, qs, name, value): point, radius = bbox.parse_xyr(value) return qs.filter(geometrie__dwithin=(point, radius)) def detailed_filter(self, qs, name, valie): return qs
class CustomsFundsFilterSet(FilterSet): fund_status = filters.ChoiceFilter(choices=settings.FUND_STATUS_CHOICE, help_text='款项状态') channel = filters.ModelChoiceFilter(queryset=DataDictsValue.objects.all(), help_text='货运渠道') pack_time_start = filters.DateTimeFilter(field_name='pack_time', lookup_expr='gte', help_text='订单(查询起始时间)') pack_time_end = filters.DateTimeFilter(field_name='pack_time', lookup_expr='lte', help_text='订单(查询结束时间)') class Meta: model = CustomsFundsInfo fields = []
class OrdFundsFilterSet(FilterSet): fund_status = filters.ChoiceFilter(choices=settings.FUND_STATUS_CHOICE, help_text='款项状态') order_status = filters.ChoiceFilter(choices=settings.ORDER_STATUS_CHOICE, help_text='订单状态') channel = filters.ModelChoiceFilter(queryset=DataDictsValue.objects.all(), help_text='服务渠道') pay_type = filters.ModelChoiceFilter(queryset=DataDictsValue.objects.all(), help_text='付款类型') order_time_start = filters.DateTimeFilter(field_name='order_time', lookup_expr='gte', help_text='订单(查询起始时间)') order_time_end = filters.DateTimeFilter(field_name='order_time', lookup_expr='lte', help_text='订单(查询结束时间)') class Meta: model = OrdFundsInfo fields = []
class OthersFundsFilterSet(FilterSet): fund_type = filters.ChoiceFilter(choices=settings.OTHER_FUND_TYPE_CHOICE, help_text='款项类型') fund_status = filters.ChoiceFilter(choices=settings.FUND_STATUS_CHOICE, help_text='款项状态') order = filters.ModelChoiceFilter(queryset=OrdFundsInfo.objects.all(), help_text='订单') freight = filters.ModelChoiceFilter(queryset=FreFundsInfo.objects.all(), help_text='运单') service = filters.ModelChoiceFilter(queryset=UsersInfo.objects.all(), help_text='款项专员') recpay_time_start = filters.DateTimeFilter(field_name='recpay_time', lookup_expr='gte', help_text='订单(查询起始时间)') recpay_time_end = filters.DateTimeFilter(field_name='recpay_time', lookup_expr='lte', help_text='订单(查询结束时间)') class Meta: model = OtherFundsInfo fields = []
class OrderStatementFilterSet(FilterSet): order_time_start = filters.DateTimeFilter(field_name='order_time', lookup_expr='gte', label='订单时间') order_time_end = filters.DateTimeFilter(field_name='order_time', lookup_expr='lte', label='订单时间')
class FreightStatementFilterSet(FilterSet): pack_time_start = filters.DateTimeFilter(field_name='pack_time', lookup_expr='gte', help_text='运单时间', label='运单时间') pack_time_end = filters.DateTimeFilter(field_name='pack_time', lookup_expr='lte', help_text='运单时间', label='运单时间')
class AlertFilter(FilterSet): """ Filters Alerts. """ def __init__(self, *args, **kwargs): super(AlertFilter, self).__init__(*args, **kwargs) # add a blank choice to ChoiceFilter options for (dummy_name, field) in self.filters.items(): if isinstance(field, django_filters.ChoiceFilter): field.extra['choices'] = tuple([('', '---------'), ] + \ list(field.extra['choices'])) collection = django_filters.ModelMultipleChoiceFilter( name='distillery', label='Collections', queryset=Distillery.objects.have_alerts()) warehouse = django_filters.ModelMultipleChoiceFilter( name='distillery__collection__warehouse', label='Warehouses', queryset=Warehouse.objects.all()) after = django_filters.DateTimeFilter(name='created_date', lookup_expr='gt') before = django_filters.DateTimeFilter(name='created_date', lookup_expr='lte') level = django_filters.MultipleChoiceFilter(choices=ALERT_LEVEL_CHOICES) status = django_filters.MultipleChoiceFilter(choices=ALERT_STATUS_CHOICES) assigned_user = django_filters.ModelChoiceFilter( name='assigned_user', queryset=AppUser.objects.all()) content = django_filters.CharFilter(name='data', label='Content', method='filter_by_content') categories = django_filters.ModelMultipleChoiceFilter( name='distillery__categories', label='Collection categories', queryset=Category.objects.all()) tags = django_filters.ModelMultipleChoiceFilter(name='tags', queryset=Tag.objects.all()) class Meta: model = Alert # List content field last so it will have fewer Alerts to # filter. The content filter requires a query to the Distillery # associated with the Alert. It's best to filter out as many # records as possible before constructing that query. fields = [ 'collection', 'after', 'before', 'level', 'status', 'assigned_user', 'content' ] @staticmethod def _get_data_query(distillery, value): """ """ text_fields = distillery.get_text_fields() field_names = [field.field_name for field in text_fields] field_keys = [name.replace('.', '__') for name in field_names] queries = [] for key in field_keys: query_exp = 'data__%s' % key kwarg = {query_exp: value} queries.append(Q(**kwarg)) field_query = join_query(queries, 'OR') return Q(distillery=distillery) & field_query @staticmethod def _get_title_query(value): """ """ return Q(title__icontains=value) def _filter_by_value(self, queryset, value): """ """ distilleries = Distillery.objects.filter( alerts__in=queryset).distinct() if distilleries: queries = [self._get_data_query(distillery, value) \ for distillery in distilleries] data_query = join_query(queries, 'OR') title_query = self._get_title_query(value) return queryset.filter(title_query | data_query) else: return queryset.none() # @timeit def filter_by_content(self, queryset, name, value): """ Takes a QuerySet of Alerts and a string value. Returns a filtered QuerySet of Alerts whose data includes the given value. """ if not value: return queryset try: return self._filter_by_value(queryset, value) except ValueError: LOGGER.error('An error occurred while filtering Alerts') return queryset