Is it good practice to evoke object and re-assign value in Python/Django?

views.py

from rest_framework import views
from rest_framework.response import Response
from .models import Category
from .services.get_categories import cached_categories
from .serializers import CategorySerializer

class CategoryTreeList(views.APIView):

    def get(self, request, format=None):
        queryset = Category.objects.all()
        cached_categories(queryset)
        serializer = CategorySerializer(cached_categories.get_cached_root_nodes(), many=True)
        return Response(serializer.data)

serializers.py

from .models import Category
from rest_framework import serializers
from .services.get_categories import cached_categories




class CategorySerializer(serializers.ModelSerializer):
    children = serializers.SerializerMethodField()

    class Meta:
        model = Category
        fields = ('id', 'name', 'children', )

    def get_children(self, obj):
        children = cached_categories.get_children(obj)
        if children:
            return CategorySerializer(children, many=True).data
        else:
            return []

get_categories.py

from ..models import Category


class CachedCategories:
    def __init__(self):
        self.queryset = None

    def __call__(self, queryset):
        self.queryset = queryset

    def split_on_dicts(self):
        objects_by_depth = {}
        for i in [obj.depth for obj in self.queryset]:
            objects_by_depth.update({f"{i}": [obj for obj in self.queryset if obj.depth == i]})

        return objects_by_depth

    def get_children(self, parent: Category):
        categories = self.split_on_dicts().get(f"{parent.depth + 1}")
        children = []
        if categories:
            for obj in categories:
                if obj.path.startswith(parent.path) and \
                        obj.depth == parent.depth + 1:
                    children.append(obj)

        return children

    def get_cached_root_nodes(self):
        return self.split_on_dicts().get("1")


cached_categories = CachedCategories()

Explaining what I want.
I built django app with nested categories.
And I wanted to pass categories to serializator with just one query. So I did it.
Then, I understood that my class CachedCategories (in get_categories.py) works only once, when I start server and load browsable API page, but it should work every time when page is reloading.
In the end it occurred to me that it was because of that get() method don't initiate class CachedCategories (in get_categories.py).
And I decided to re-assign queryset value after every page loading (I reassign value in get() method of CategoryTreeList class in views.py). To get such result I override __call__ method in CachedCategories (in get_categories.py).
So, Is it good practice to evoke object and re-assign value?
Maybe, there are more concise ways to solve my problem?

Back to Top