About Retrieving the Proxy Model Instance

Django doesn't have a default way to switch to an instance of a proxy model when you have an instance of the original model. But this can be achieved with the following custom template filter (or analogous helper function):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# core/templatetags/core_filters.py
from django import template

register = template.Library()

@register.filter
def get_proxy_model_instance(obj, app_model):
    from django.apps import apps
    app_label, model_name = app_model.split(".")
    proxy_model = apps.get_model(app_label, model_name)
    proxy_instance = proxy_model()
    for attr in [f.name for f in proxy_model._meta.fields] + ["_state"]:
        setattr(proxy_instance, attr, getattr(obj, attr))
    return proxy_instance

Here is how it would be used in the template:

1
2
3
4
5
6
7
{% load core_filters %}

{% for group in editors %}
  {% with role=group|get_proxy_model_instance:"accounts.Role" %}
    {{ role.get_non_active_users }}
  {% endwith %}
{% endfor %}

Tips and Tricks Programming Architecture Django 4.x Django 3.2 Django 2.2