Skip to content

Commit

Permalink
django-filter description bugfix #234
Browse files Browse the repository at this point in the history
  • Loading branch information
tfranzel committed Jan 10, 2021
1 parent db3819f commit a32027f
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 22 deletions.
35 changes: 25 additions & 10 deletions drf_spectacular/contrib/django_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,16 @@ def get_schema_operation_parameters(self, auto_schema, *args, **kwargs):

parameters = []
for field_name, field in filterset_class.base_filters.items():
schema, description, enum = (
self.resolve_filter_field(auto_schema, model, filterset_class, field)
)
parameters.append(build_parameter_type(
name=field_name,
required=field.extra['required'],
location=OpenApiParameter.QUERY,
description=field.label if field.label is not None else field_name,
schema=self.resolve_filter_field(auto_schema, model, filterset_class, field),
enum=[c for c, _ in field.extra.get('choices', [])],
description=description,
schema=schema,
enum=enum,
))

return parameters
Expand All @@ -56,17 +59,29 @@ def resolve_filter_field(self, auto_schema, model, filterset_class, filter_field
filter_method_hints = typing.get_type_hints(filter_method)

if 'value' in filter_method_hints and is_basic_type(filter_method_hints['value']):
return build_basic_type(filter_method_hints['value'])
schema = build_basic_type(filter_method_hints['value'])
else:
schema = self.map_filter_field(filter_field)
else:
path = filter_field.field_name.split('__')
model_field = follow_field_source(model, path)

if isinstance(model_field, models.Field):
schema = auto_schema._map_model_field(model_field, direction=None)
else:
return self.map_filter_field(filter_field)
schema = self.map_filter_field(filter_field)

path = filter_field.field_name.split('__')
model_field = follow_field_source(model, path)
if 'choices' in filter_field.extra:
enum = [c for c, _ in filter_field.extra['choices']]
else:
enum = schema.pop('enum', None)

if isinstance(model_field, models.Field):
return auto_schema._map_model_field(model_field, direction=None)
if filter_field.label is not None:
description = filter_field.label
else:
return self.map_filter_field(filter_field)
description = schema.pop('description', None)

return schema, description, enum

def map_filter_field(self, filter_field):
from django_filters.rest_framework import filters
Expand Down
8 changes: 6 additions & 2 deletions tests/contrib/test_django_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ class OtherSubProduct(models.Model):


class Product(models.Model):
category = models.CharField(max_length=10, choices=(('A', 'aaa'), ('B', 'b')))
category = models.CharField(
max_length=10,
choices=(('A', 'aaa'), ('B', 'b')),
help_text='some category description'
)
in_stock = models.BooleanField()
price = models.FloatField()
other_sub_product = models.ForeignKey(OtherSubProduct, on_delete=models.CASCADE)
Expand All @@ -52,7 +56,7 @@ class Meta:

class ProductFilter(FilterSet):
# explicit filter declaration
max_price = NumberFilter(field_name="price", lookup_expr='lte')
max_price = NumberFilter(field_name="price", lookup_expr='lte', label='highest price')
max_sub_price = NumberFilter(field_name="subproduct__sub_price", lookup_expr='lte')
sub = NumberFilter(field_name="subproduct", lookup_expr='exact')
int_id = NumberFilter(method='filter_method_typed')
Expand Down
15 changes: 5 additions & 10 deletions tests/contrib/test_django_filters.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,51 +15,44 @@ paths:
- A
- B
type: string
description: category
description: some category description
- in: query
name: in_stock
schema:
type: boolean
description: in_stock
- in: query
name: int_id
schema:
type: integer
description: int_id
- in: query
name: max_price
schema:
type: number
format: float
description: max_price
description: highest price
- in: query
name: max_sub_price
schema:
type: number
format: float
description: max_sub_price
- in: query
name: number_id
schema:
type: number
description: number_id
- in: query
name: other_sub_product__uuid
schema:
type: string
format: uuid
description: other_sub_product__uuid
- in: query
name: sub
schema:
type: integer
description: sub
- in: query
name: subproduct__sub_price
schema:
type: number
format: float
description: subproduct__sub_price
tags:
- products
security:
Expand Down Expand Up @@ -113,7 +106,9 @@ components:
type: integer
readOnly: true
category:
$ref: '#/components/schemas/CategoryEnum'
allOf:
- $ref: '#/components/schemas/CategoryEnum'
description: some category description
in_stock:
type: boolean
price:
Expand Down

0 comments on commit a32027f

Please sign in to comment.