mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-11-04 15:15:42 +00:00 
			
		
		
		
	Add new report filters for accessing database tables (#8560)
* Add new report filters for accessing database tables * Simplify * Handle exception * Add docs * Update docstrings
This commit is contained in:
		@@ -78,6 +78,78 @@ To return an element corresponding to a certain key in a container which support
 | 
				
			|||||||
{% endraw %}
 | 
					{% endraw %}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Database Helpers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					A number of helper functions are available for accessing database objects:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### filter_queryset
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The `filter_queryset` function allows for arbitrary filtering of the provided querysert. It takes a queryset and a list of filter arguments, and returns a filtered queryset.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					::: report.templatetags.report.filter_queryset
 | 
				
			||||||
 | 
					    options:
 | 
				
			||||||
 | 
					        show_docstring_description: false
 | 
				
			||||||
 | 
					        show_source: False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					!!! info "Provided QuerySet"
 | 
				
			||||||
 | 
					    The provided queryset must be a valid Django queryset object, which is already available in the template context.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					!!! warning "Advanced Users"
 | 
				
			||||||
 | 
					    The `filter_queryset` function is a powerful tool, but it is also easy to misuse. It assumes that the user has a good understanding of Django querysets and the underlying database structure.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Example
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In a report template which has a `PurchaseOrder` object available in its context, fetch any line items which have a received quantity greater than zero:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```html
 | 
				
			||||||
 | 
					{% raw %}
 | 
				
			||||||
 | 
					{% load report %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% filter_queryset order.lines.all received__gt=0 as received_lines %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<ul>
 | 
				
			||||||
 | 
					  {% for line in received_lines %}
 | 
				
			||||||
 | 
					  <li>{{ line.part.part.full_name }} - {{ line.received }} / {{ line.quantity }}</li>
 | 
				
			||||||
 | 
					    {% endfor %}
 | 
				
			||||||
 | 
					</ul>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% endraw %}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### filter_db_model
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The `filter_db_model` function allows for filtering of a database model based on a set of filter arguments. It takes a model class and a list of filter arguments, and returns a filtered queryset.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					::: report.templatetags.report.filter_db_model
 | 
				
			||||||
 | 
					    options:
 | 
				
			||||||
 | 
					        show_docstring_description: false
 | 
				
			||||||
 | 
					        show_source: False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Example
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Generate a list of all active customers:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```html
 | 
				
			||||||
 | 
					{% raw %}
 | 
				
			||||||
 | 
					{% load report %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% filter_db_model company.company is_customer=True active=True as active_customers %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<ul>
 | 
				
			||||||
 | 
					    {% for customer in active_customers %}
 | 
				
			||||||
 | 
					    <li>{{ customer.name }}</li>
 | 
				
			||||||
 | 
					    {% endfor %}
 | 
				
			||||||
 | 
					</ul>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% endraw %}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Advanced Database Queries
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					More advanced database filtering should be achieved using a [report plugin](../extend/plugins/report.md), and adding custom context data to the report template.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Number Formatting
 | 
					## Number Formatting
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### format_number
 | 
					### format_number
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,8 +8,10 @@ from decimal import Decimal
 | 
				
			|||||||
from typing import Any, Optional
 | 
					from typing import Any, Optional
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from django import template
 | 
					from django import template
 | 
				
			||||||
 | 
					from django.apps.registry import apps
 | 
				
			||||||
from django.conf import settings
 | 
					from django.conf import settings
 | 
				
			||||||
from django.core.exceptions import ValidationError
 | 
					from django.core.exceptions import ValidationError
 | 
				
			||||||
 | 
					from django.db.models.query import QuerySet
 | 
				
			||||||
from django.utils.safestring import SafeString, mark_safe
 | 
					from django.utils.safestring import SafeString, mark_safe
 | 
				
			||||||
from django.utils.translation import gettext_lazy as _
 | 
					from django.utils.translation import gettext_lazy as _
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -29,6 +31,50 @@ register = template.Library()
 | 
				
			|||||||
logger = logging.getLogger('inventree')
 | 
					logger = logging.getLogger('inventree')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@register.simple_tag()
 | 
				
			||||||
 | 
					def filter_queryset(queryset: QuerySet, **kwargs) -> QuerySet:
 | 
				
			||||||
 | 
					    """Filter a database queryset based on the provided keyword arguments.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Arguments:
 | 
				
			||||||
 | 
					        queryset: The queryset to filter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Keyword Arguments:
 | 
				
			||||||
 | 
					        field (any): Filter the queryset based on the provided field
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Example:
 | 
				
			||||||
 | 
					        {% filter_queryset companies is_supplier=True as suppliers %}
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    return queryset.filter(**kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@register.simple_tag()
 | 
				
			||||||
 | 
					def filter_db_model(model_name: str, **kwargs) -> QuerySet:
 | 
				
			||||||
 | 
					    """Filter a database model based on the provided keyword arguments.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Arguments:
 | 
				
			||||||
 | 
					        model_name: The name of the Django model - including app name (e.g. 'part.partcategory')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Keyword Arguments:
 | 
				
			||||||
 | 
					        field (any): Filter the queryset based on the provided field
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Example:
 | 
				
			||||||
 | 
					        {% filter_db_model 'part.partcategory' is_template=True as template_parts %}
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    app_name, model_name = model_name.split('.')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        model = apps.get_model(app_name, model_name)
 | 
				
			||||||
 | 
					    except Exception:
 | 
				
			||||||
 | 
					        return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if model is None:
 | 
				
			||||||
 | 
					        return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    queryset = model.objects.all()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return filter_queryset(queryset, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@register.simple_tag()
 | 
					@register.simple_tag()
 | 
				
			||||||
def getindex(container: list, index: int) -> Any:
 | 
					def getindex(container: list, index: int) -> Any:
 | 
				
			||||||
    """Return the value contained at the specified index of the list.
 | 
					    """Return the value contained at the specified index of the list.
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user