from urllib.parse import urlencode, urlparse, urlunparse from django.conf import settings from django.urls import reverse def build_canonical_url(request, base_url=None, params=None): if base_url is None: base_url = request.path elif base_url.startswith('/'): base_url = base_url else: parsed = urlparse(base_url) base_url = parsed.path + ('?' + parsed.query if parsed.query else '') filtered_params = { k: v for k, v in (params or {}).items() if v not in (None, '', [], {}) and not (k == 'page' and str(v) == '1') } query_string = urlencode(filtered_params) path = base_url if query_string: path += '?' + query_string domain = getattr(settings, 'CANONICAL_URL_DOMAIN', None) if domain: return domain.rstrip('/') + path return request.build_absolute_uri(path)