Django template filter not raising exception when error occurs

I am building a custom template filter in Django to check if a user has permissions to view certain links in my navigation.

I am running into an issue where I want to know if the argument passed in is bad, which is an app_label, so I can throw an exception on that front and be notified.

Here is my HTML of the filter in use, that works without the or but with it, the conditional simply returns False without throwing the exception which is where I am confused.

Note: I have an app named 'reports', not 'repordts' so the exception should definitely be thrown.

{% if request|has_perm_for_app_with_property:'repordts' or request|has_perm_for_app_with_property:'staff_reports' %}

This version throws the exception correctly:

{% if request|has_perm_for_app_with_property:'repordts' %}

Here is the filter code:

def has_perm_for_app_with_property(request, app_label):
    user = request.user
    # ensure prop is set in session
    if not request.session.get('property'):
        return False


    # gather perms and show error if bad name
    perms_for_app = Permission.objects.filter(content_type__app_label=app_label)
    if not perms_for_app:
        raise Exception(f'No Perms for App: {app_label}')
    # check to ensure the permission passed is accurate
    allowed = any([user.has_perm(perm) for perm in perms_for_app])

    return allowed
{% if request|has_perm_for_app_with_property:'repordts' %}
{{ request|has_perm_for_app_with_property:'repordts' }}
{% else %}
{{ request|has_perm_for_app_with_property:'staff_reports' }}
{% endif %}

This code will throw the exception if 'repordts' is passed in, but will also check if the user has permission for 'staff_reports' if the first check returns False.

Alternatively, you can use the "try-except" block to catch the exception and handle it in a more specific way.

{% try %}
{{ request|has_perm_for_app_with_property:'repordts' }}
{% except Exception as e %}
{{ e }}
{% endtry %}

This way you can catch the exception and handle it in a more specific way, instead of using a simple if-else condition.

Back to Top