Skip to content

Commit

Permalink
make choices_queryset not dependent on the time range and therefore m…
Browse files Browse the repository at this point in the history
…uch quicker
  • Loading branch information
PetrDlouhy committed Oct 18, 2023
1 parent 279fefd commit 30773b6
Showing 1 changed file with 17 additions and 12 deletions.
29 changes: 17 additions & 12 deletions admin_tools_stats/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -889,6 +889,15 @@ def get_dynamic_field(self):
query = self.stats.get_queryset().all().query
return query.resolve_ref(field_name).field

def get_related_model_and_field(self, field_name):
"""Traverse the field_name to get the related model and end target field."""
base_model = self.stats.get_queryset().model
fields = field_name.split("__")
for rel in fields[:-1]: # omit the last segment since it's the field in the target model
relation = base_model._meta.get_field(rel)
base_model = relation.related_model
return base_model, fields[-1] # returns target model and target field name

@memoize(60 * 60 * 24 * 7)
def _get_dynamic_choices(
self,
Expand Down Expand Up @@ -942,19 +951,15 @@ def _get_dynamic_choices(
)
end_time = time_until
date_filters["%s__lte" % self.stats.date_field_name] = end_time
choices_queryset = self.stats.get_queryset().filter(
**date_filters,
)
if user and not user.has_perm("admin_tools_stats.view_dashboardstats"):
if not self.stats.user_field_name:
raise Exception(
"User field must be defined to enable charts for non-superusers"
)
choices_queryset = choices_queryset.filter(**{self.stats.user_field_name: user})
choices_queryset = choices_queryset.values_list(
field_name,

# Obtain the related model and the target field dynamically from the field_name
related_model, target_field = self.get_related_model_and_field(field_name)

choices_queryset = related_model.objects.values_list(
target_field, # targeting the final field in the related model
flat=True,
).distinct()

if count_limit:
choices_queryset = choices_queryset.annotate(
f_count=self.stats.get_operation(operation_choice, operation_field_choice),
Expand All @@ -965,7 +970,7 @@ def _get_dynamic_choices(
other_choices_queryset: List[str] = choices_list[count_limit:]
choices_queryset = choices_list[:count_limit]
else:
choices_queryset = choices_queryset.order_by(field_name)
choices_queryset = choices_queryset.order_by(target_field)
choices.update(
((i, (i, fchoices[i] if i in fchoices else i)) for i in choices_queryset),
)
Expand Down

0 comments on commit 30773b6

Please sign in to comment.