Custom formatters

A list of validators and formatters that can be overridden in Salesman.

Price formatter

Displaying prices in Salesman is controlled using a price formatter function. The default formatter function is set to salesman.core.utils.format_price() and returns a value formated with two decimal places.

Tip

Price formatter can be used (among other things) to display a price with a symbol or even a converted price to another currency based on the request that’s received in the context.

You can change the price formatter by providing a dotted path in SALESMAN_PRICE_FORMATTER setting that points to your custom formatter function.

def format_price(value: Decimal, context: dict = {}) -> str:
    """
    Default price format function. Can be overriden by providing a
    dotted path to a function in ``SALESMAN_PRICE_FORMATTER`` setting.

    Args:
        value (Decimal): Number value to be formatted
        context (dict, optional): Format context data. Defaults to {}.

    Returns:
        str: Formatted price as a string
    """
    return f'{value:.2f}'

Your custom function should accept a value argument of type Decimal and a context dictionary that contains additional render data like request and either the basket or order object. The function should return a formatted price as a string.

Admin JSON formatter

When displaying JSON data in admin, a formatter function is used. The default function salesman.admin.utils.format_json() uses the Pygments library to create the default JSON display. You can override the JSON formatter by providing a dotted path to a function in SALESMAN_ADMIN_JSON_FORMATTER setting.

def format_json(value: dict, context: dict = {}) -> str:
    """
    Format json and add color using pygments with fallback.

    Args:
        value (dict): Dict to be formated to json
        context (dict, optional): Format context data. Defaults to {}.

    Returns:
        str: JSON formated html string
    """
    value = json.dumps(value, indent=2)
    value = pygments_highlight(value, 'json', 'tango')
    style = pygments_css('tango')
    styled = context.get('styled', True)  # Used for testing.
    if styled and style:
        html = (
            f'<style>{style}</style>'
            f'<pre class="highlight" style="margin: 0; padding: 1em;">{value}</pre>'
        )
    else:
        html = f'<pre style="margin: 0;">{value}</pre>'
    return format_html('<div>{}</div>', mark_safe(html))

Your custom formatter should accept a dictionary value and return the HTML string. It also receives a context dictionary with additional context. Either an order or order_item boolean will be passed in depending on the formatting location.

Admin Customer formatter

To display customer on an order, a formatter function is used. The default function salesman.admin.utils.format_customer() returns the link to the default User models for both the Django and Wagtail admins. You can override the Customer formatter by providing a dotted path to a function in SALESMAN_ADMIN_CUSTOMER_FORMATTER setting.

def format_customer(user: User, context: dict = {}) -> str:
    """
    Format the customer display in admin orders.

    Args:
        user (User): Order user.
        context (dict, optional): Format context data. Defaults to {}.

    Returns:
        str: Formatted customer display as string
    """
    if context.get("wagtail", False):
        url_name = 'wagtailusers_users:edit'
    else:
        url_name = 'admin:auth_user_change'

    try:
        url = reverse(url_name, args=[user.pk])
        return mark_safe(f'<a href="{url}">{user}</a>')
    except NoReverseMatch:  # pragma: no cover
        return str(user)

Your custom formatter should accept a user instnance and return a string. It also receives a context dictionary with additional context.