From 9a40d85a54803e4c735bbe1a6f5b417ae391adc9 Mon Sep 17 00:00:00 2001 From: Dev Aggarwal Date: Tue, 17 Oct 2023 15:14:15 +0530 Subject: [PATCH] make visitor click info admin views faster --- gooeysite/custom_filters.py | 10 ++++++++-- url_shortener/admin.py | 33 ++++++++++++++++++++++++--------- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/gooeysite/custom_filters.py b/gooeysite/custom_filters.py index 1c62c896d..221b422a9 100644 --- a/gooeysite/custom_filters.py +++ b/gooeysite/custom_filters.py @@ -1,4 +1,5 @@ import json +import typing from django.db import DataError from django.db.models import F, Func, QuerySet, Count @@ -7,7 +8,10 @@ def json_field_nested_lookup_keys( - qs: QuerySet, field: str, max_depth: int = 3 + qs: QuerySet, + field: str, + max_depth: int = 3, + exclude_keys: typing.Iterable[str] = (), ) -> list[str]: nested_keys = [field] for _ in range(max_depth): @@ -23,6 +27,7 @@ def json_field_nested_lookup_keys( .distinct() .values_list("keys", flat=True) ) + if not child in exclude_keys ) except DataError: next_keys.append(parent) @@ -36,6 +41,7 @@ def related_json_field_summary( qs: QuerySet = None, query_param: str = None, instance_id: int = None, + exclude_keys: typing.Iterable[str] = (), ): if query_param is None: try: @@ -56,7 +62,7 @@ def related_json_field_summary( if qs is None: qs = manager.all() - nested_keys = json_field_nested_lookup_keys(qs, field) + nested_keys = json_field_nested_lookup_keys(qs, field, exclude_keys=exclude_keys) results = { key.split(field + "__")[-1]: [ diff --git a/url_shortener/admin.py b/url_shortener/admin.py index ab2c349ed..58a74d7cb 100644 --- a/url_shortener/admin.py +++ b/url_shortener/admin.py @@ -14,6 +14,17 @@ ) from url_shortener import models +JSON_FIELDS = ["browser", "device", "os", "ip_data"] + +EXCLUDE_KEYS = { + "version", + "version_string", + "ip", + "asn_start", + "asn_end", + "asn_code", +} + @admin.register(models.ShortenedURL) class ShortenedURLAdmin(admin.ModelAdmin): @@ -66,8 +77,10 @@ def view_visitors(self, obj: models.ShortenedURL): @admin.display(description="Visitor Summary") def view_visitor_summary(self, surl: models.ShortenedURL): html = "" - for field in ["browser", "device", "os", "ip_data"]: - results = related_json_field_summary(surl.visitors, field) + for field in JSON_FIELDS: + results = related_json_field_summary( + surl.visitors, field, exclude_keys=EXCLUDE_KEYS + ) html += "

" + field.replace("_", " ").capitalize() + "

" html += loader.render_to_string( "anaylsis_result.html", context=dict(results=results) @@ -76,14 +89,19 @@ def view_visitor_summary(self, surl: models.ShortenedURL): return html -def jsonfieldlistfilter(field: str): +def jsonfieldlistfilter( + field: str, + exclude_keys=EXCLUDE_KEYS, +): class JSONFieldListFilter(admin.SimpleListFilter): title = field.replace("_", " ").capitalize() parameter_name = field def lookups(self, request, model_admin): qs = model_admin.model.objects.all() - lookups = json_field_nested_lookup_keys(qs, field) + lookups = json_field_nested_lookup_keys( + qs, field, exclude_keys=exclude_keys + ) return [ ( json.dumps([k, v]), @@ -106,12 +124,8 @@ def queryset(self, request, queryset): @admin.register(models.VisitorClickInfo) class VisitorClickInfoAdmin(admin.ModelAdmin): list_filter = [ - jsonfieldlistfilter("browser"), - jsonfieldlistfilter("device"), - jsonfieldlistfilter("os"), - jsonfieldlistfilter("ip_data"), "created_at", - ] + ] + [jsonfieldlistfilter(name) for name in JSON_FIELDS] search_fields = ["ip_address", "user_agent", "ip_data"] + [ f"shortened_url__{field}" for field in ShortenedURLAdmin.search_fields ] @@ -122,4 +136,5 @@ class VisitorClickInfoAdmin(admin.ModelAdmin): "created_at", ] ordering = ["created_at"] + autocomplete_fields = ["shortened_url"] actions = [export_to_csv, export_to_excel]