I have a large Django Project that has hundreds of views already. I am creating a tasks
feature where users are able to complete specific tasks associated with the specific application in the project they are using. I have multiple interfaces (aka Django apps in the project) : admin
, management
, onsite
, etc... and each interface has its own navigation with a tasks
link.
What I want is to be able to change the color of this link if a user is in an interface where a task
has yet to be completed.
This is easy to check in each view and then I could universally render the correct color for the link based on a variable passed into the view, but that is extremely tedious with hundreds of views.
I suppose I could add a filter in each interface/Django App to simplify this a bit, but is that the most simple solution?
Here is an example of the method I want to be called in each interface's navigation:
from objects_client.task_models.task_models import Tasks
def does_interface_have_open_tasks(current_interface, db_alias):
if Tasks.objects.using(db_alias)\
.filter(interface=current_interface, completed=0).exists():
return True
return False
I ended up using a Context Processor
to solve my needs like I show below:
import traceback
from objects_client.task_models.task_models import Tasks
def universally_used_data(request):
# I use multiple DBs
db_alias = request.session.get('db_alias')
# dictionary for global context values
dictionary_to_return = dict()
# interfaces and URL equivalents
interface_dictionary = {
'adm': 'admin',
'mgt': 'management',
'onsite': 'onsite',
'secu': 'security',
'maint': 'maintenance'
}
try:
# get interface url
short_url = request.path[1:-1].split('/')[1]
# get interface from dictionary above
interface = interface_dictionary.get(short_url)
dictionary_to_return['SHORT_URL'] = short_url
dictionary_to_return['INTERFACE'] = interface
# see if there is an open task...
if Tasks.objects.using(db_alias) \
.filter(interface=interface, completed=0).exists():
dictionary_to_return['OPEN_TASKS'] = True
else:
dictionary_to_return['OPEN_TASKS'] = False
except Exception as ex:
print(ex, traceback.format_exc())
return dictionary_to_return
Here is how I load the Context Processor
:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
os.path.join(BASE_DIR, 'templates'),
...
]
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
...
# custom processors
'utils.context_processors.context_processors.universally_used_data'
],
},
},
]
Then I can just call the this variable in the template like so to change an HTML element's color, no {% load [whatever] %}
or anything:
{% if OPEN_TASKS %}
style="color:red;"
{% endif %}
Thank you @Daniel Roseman for the suggestion/comment. This had me stumped for a bit :)