How to do it...

For these template tags, we will be using the simple_tag decorator that parses the components and requires you to just define the rendering function, as follows:

  1. First, let's add a helper method for putting together the query strings that each of our tags will output:
# utils/templatetags/utility_tags.py
from urllib.parse import urlencode

from django import template
from django.utils.encoding import force_str

register = template.Library()


def construct_query_string(context, query_params):
# empty values will be removed
query_string = context["request"].path
if len(query_params):
encoded_params = urlencode([
(key, force_str(value))
for (key, value) in query_params if value
]).replace("&", "&")
query_string += f"?{encoded_params}"
return query_string


"""TAGS"""
# ...
  1. Then, we will create the {% modify_query %} template tag:
@register.simple_tag(takes_context=True)
def modify_query(context, *params_to_remove, **params_to_change):
"""Renders a link with modified current query parameters"""
query_params = []
get_data = context["request"].GET
for key, last_value in get_data.items():
value_list = get_data.getlist(key)
if key not in params_to_remove:
# don't add key-value pairs for params_to_remove
if key in params_to_change:
# update values for keys in params_to_change
query_params.append((key, params_to_change[key]))
params_to_change.pop(key)
else:
# leave existing parameters as they were
# if not mentioned in the params_to_change
for value in value_list:
query_params.append((key, value))
# attach new params
for key, value in params_to_change.items():
query_params.append((key, value))
return construct_query_string(context, query_params)
  1. Next, let's create the {% add_to_query %} template tag:
@register.simple_tag(takes_context=True)
def add_to_query(context, *params_to_remove, **params_to_add):
"""Renders a link with modified current query parameters"""
query_params = []
# go through current query params..
get_data = context["request"].GET
for key, last_value in get_data.items():
value_list = get_data.getlist(key)
if key not in params_to_remove:
# don't add key-value pairs which already
# exist in the query
if (key in params_to_add
and params_to_add[key] in value_list):
params_to_add.pop(key)
for value in value_list:
query_params.append((key, value))
# add the rest key-value pairs
for key, value in params_to_add.items():
query_params.append((key, value))
return construct_query_string(context, query_params)
  1. Lastly, let's create the {% remove_from_query %} template tag:
@register.simple_tag(takes_context=True)
def remove_from_query(context, *args, **kwargs):
"""Renders a link with modified current query parameters"""
query_params = []
# go through current query params..
get_data = context["request"].GET
for key, last_value in get_data.items():
value_list = get_data.getlist(key)
# skip keys mentioned in the args
if key not in args:
for value in value_list:
# skip key-value pairs mentioned in kwargs
if not (key in kwargs and
str(value) == str(kwargs[key])):
query_params.append((key, value))
return construct_query_string(context, query_params)
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.136.154.103