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?