Custom validators & formatters

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

Address validator

During the checkout process, both the shipping and billing addresses can be specified. The default address validator is set to salesman.checkout.utils.validate_address() that simply makes both address fields required to be entered by the customer.

This behavior can be overridden by providing a dotted path in SALESMAN_ADDRESS_VALIDATOR setting that points to your custom validator function.

Tip

To validate a specific address format split the text by \n character and validate each line.

def validate_address(value: str, context: dict = {}) -> str:
    """
    Default address validator function. Can be overriden by providing a
    dotted path to a function in ``SALESMAN_ADDRESS_VALIDATOR`` setting.

    Args:
        value (str): Address text to be validated
        context (dict, optional): Validator context data.

    Raises:
        ValidationError: In case address is not valid

    Returns:
        str: Validated value
    """
    if not value:
        raise ValidationError(_("Address is required."))
    return value

Your custom validator should accept a text value and return the validated version. It also receives a context dictionary with additional context data like request, a basket object and address type (set to either shipping or billing).

Extra validator

Both the basket and basket item objects have an extra JSON field to store additional information that can be changed or updated via the API. By default no validation is enforced through a placeholder salesman.basket.utils.validate_extra() function.

You can add custom validation by providing a dotted path in SALESMAN_EXTRA_VALIDATOR setting that points to your custom validator function.

def validate_extra(value: dict, context: dict = {}) -> dict:
    """
    Default extra validator function. Can be overriden by providing a
    dotted path to a function in ``SALESMAN_EXTRA_VALIDATOR`` setting.

    Args:
        value (str): Extra dict to be validated
        context (dict, optional): Validator context data.

    Raises:
        ValidationError: In case data is not valid

    Returns:
        dict: Validated value
    """
    return value

Your custom validator should accept a dictionary value and return the validated version. It also receives a context dictionary with additional context data like request, a basket object and basket_item in case validation is happening on the basket item.

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.