Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/singularit-de/django-rest-aggregation
https://github.com/singularit-de/django-rest-aggregation
Last synced: 24 days ago
JSON representation
- Host: GitHub
- URL: https://github.com/singularit-de/django-rest-aggregation
- Owner: singularit-de
- License: mit
- Created: 2023-11-29T12:34:53.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2024-10-29T09:43:07.000Z (3 months ago)
- Last Synced: 2024-12-30T23:35:54.073Z (26 days ago)
- Language: Python
- Size: 71.3 KB
- Stars: 1
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
You can find the original Project here: https://github.com/kit-oz/drf-aggregation
# Django Rest Framework Aggregation
---
A simple Django Rest Framework extension to add aggregation endpoints to your API.
Key features:
- count, sum, average, minimum, maximum
- grouping by multiple fields
- filtering and ordering---
## Installation
To install, use pip
pip install django-rest-aggregation
## Quickstart
Inherit the **AggregationMixin** in your ViewSet.
```python
from django_rest_aggregation.mixins import AggregationMixin...
class BookViewSet(GenericViewSet, AggregationMixin):
queryset = Book.objects.all()
serializer_class = BookSerializer
```Register the ViewSet in your `urls.py`. The default aggregation endpoint is **{base_url}/aggregation/**.
```python
router = DefaultRouter()
router.register(r'book', BookViewSet)urlpatterns = [
path('', include(router.urls)),
# or
path('book/custom/endpoint/', BookViewSet.as_view({'get': 'aggregation'}))
]
```Get the aggregation results by sending a GET request to the aggregation endpoint.
| URL | What it does |
|-------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------|
| ```/book/aggregation/?aggregation=count ``` | Get the total number of books |
| ```/book/aggregation/?aggregation=maximum&aggregation_field=price``` | Get the most expensive book |
| ```/book/aggregation/?aggregation=average&aggregation_field=rating&group_by=author``` | Get the average rating grouped by author |
| ```/book/aggregation/?aggregation=sum&aggregation_field=pages&group_by=author&value__gt=1000``` | Get the sum of all pages grouped by authors which are greater than 1000 |## Parameter overview
### URL Parameters
| query parameter | description | example |
|-------------------|--------------------------------------------|-------------------------------|
| aggregation | determines the type of aggregation | ```aggregation=sum``` |
| aggregation_field | the field to aggregate on | ```aggregation_field=price``` |
| group_by | the field on which the queryset is grouped | ```group_by=author``` |
| value | the value to filter the queryset | ```value__gt=1000``` |### View Class Variables
| class variable | description | example |
|------------------------------|------------------------------------------------------|-----------------------------------------------------|
| aggregation_name | changes the default value name | ```aggregation_name=foo``` |
| aggregation_serializer_class | Sets a custom serializer for the queryset | ```aggregation_serializer_class=CustomSerializer``` |
| aggregated_filtering_class | Sets a FilterSet Class for filtering the value field | ```aggregated_filtering_class=ValueFilter``` |
| aggregated_filterset_fields | A shortcut for setting a value Filtersets | ```aggregated_filterset_fields=[lt, lte, gt]``` |## Aggregations
Available aggregations are:
- count
- sum
- average
- minimum
- maximumThey can be used by adding the mandatory **aggregation** parameter to the request URL.
/book/aggregation/?aggregation=count
### Aggregation Field
The aggregation field is the field to aggregate on.
It can be used by adding the **aggregation_field** parameter to the request URL.
This is a mandatory parameter for the **sum**, **average**, **minimum** and **maximum** aggregations.
Both model fields and annotated fields can be used./book/aggregation/?aggregation=sum&aggregation_field=price
You can also use the double underscore notation to aggregate on related model fields.
/book/aggregation/?aggregation=sum&aggregation_field=author__age
If the aggregation is sum or average, the aggregation field must be a numeric field. If the aggregation is min or
max, the aggregation field must be date or numeric field.## Grouping
Grouping is done by adding the **group_by** parameter to the request URL.
Again, model fields and annotated fields can be used./book/aggregation/?aggregation=count&group_by=author
You can group throughout multiple model relations (ForeignKey & ManyToMany Fields) by using the double underscore
notation./store/aggregation/?aggregation=count&group_by=books__author__age
To group by multiple fields, separate them with a comma.
/book/aggregation/?aggregation=count&group_by=author,genre
## Filtering & Ordering
To filter the queryset, you can use the standard Django Filter Backend.
That implies:
- filtering before aggregation/book/aggregation/?aggregation=count&group_by=author&pages__gt=100
- filtering after aggregation
/book/aggregation/?aggregation=count&group_by=author&value__gt=5
- combined filtering/book/aggregation/?aggregation=count&group_by=author&pages__gt=100&value__gt=100
To control which filtering options are available, you can use the **aggregated_filtering_class** class variable.
This sets a custom FilterSet Class for filtering the value field.```python
class BookViewSet(GenericViewSet, AggregationMixin):
queryset = Book.objects.all()
serializer_class = BookSerializer
aggregated_filtering_class = ValueFilterclass ValueFilter(filters.FilterSet):
value__gte = filters.NumberFilter(field_name='test123', lookup_expr='gte')
value__lte = filters.NumberFilter(field_name='test123', lookup_expr='lte')class Meta:
fields = ['test123__gte', 'test123__lte']
```
A shortcut for setting value Filtersets is the **aggregated_filtering_fields** class variable.
This automatically creates a FilterSet class for filtering the value field.```python
class BookViewSet(GenericViewSet, AggregationMixin):
queryset = Book.objects.all()
serializer_class = BookSerializer
aggregated_filtering_fields = ['lt', 'lte', 'gt']
```
You can use 'lt', 'lte', 'gt', 'gte', 'exact' and __all__ as values for the **aggregated_filtering_fields** class variable.Fields available for ordering the result are taken from the `aggregated_ordering_fields` attribute.
```python
class BookViewSet(GenericViewSet, AggregationMixin):
queryset = Book.objects.all()
serializer_class = BookSerializer
aggregated_ordering_fields = ['value', 'grouped_by_field']
```
if this is not set available fields are taken from the usual `ordering_fields` attribute.
The reason for this behaviour is to accommodate interplay with the often used `OrderingFilter`
```python
class BookViewSet(GenericViewSet, AggregationMixin):
queryset = Book.objects.all()
serializer_class = BookSerializer
ordering_fields = ['page_count', 'author']
```
If no ordering fields of any kind are specified or the list contains `"__all__"` any passed ordering will be tried to be applied.
``ordering_fields = __all__`` is also possible.