Django3/DRF: Custom Queryset __init__() gets called multiple times. [ Chaining Querysets is applied ]

166 views Asked by At

Greeting there !

i have built a custom queryset and i have noticed that its __init__() method gets called multiple times.

let's take into consideration that i am also applyingQueryset Chaining

models.py

class Todo(...):
    ...
    objects = TodoQueryset.as_manager()

manager.py

from types import MethodType

from django.conf import settings
from django.db import models
from django.utils import timezone

from .settings import TODO_PRIORITY, TODO_STATUS, today_start_date


class TodoQueryset(models.QuerySet):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.priorities = TODO_PRIORITY   
        print('\t weird 0')

    def starting_from_today(self):
        return self.filter(start_time__gte=today_start_date)

    def flag_as_missed(self):
        """ Flag Todos which end_time is lower than the current datetime as `TODO_MISSED` """
        return self.filter(status=settings.TODO_PROGRESS, end_time__lt=timezone.now).update(status=settings.TODO_MISSED)

    def specific(self, priority=None, status=None):
        """
            Fetch Todos with a specific priority:
                => {self.}request.user.todos.specific(priority='HIGH')

            Or call the specific method set for each priority:
                => {self.}request.user.todos.high() // NOT IMPLEMENTED YET
        """

        assert priority is not None or status is not None, '.specific() must be called with either `status=...` or `priority=...`, got None instead.'
        return self.filter(priority=priority.upper())

serializers.py

class TodoListSerializer(serializers.Serializer):
    todo_id = serializers.IntegerField(read_only=True)
    author_id = serializers.IntegerField(read_only=True)
    content = serializers.CharField(read_only=True)
    start_time = serializers.DateTimeField(read_only=True)
    end_time = serializers.DateTimeField(read_only=True)
    timestamp = serializers.DateTimeField(read_only=True)
    priority = serializers.CharField(read_only=True)
    status = serializers.CharField(read_only=True)
    path = serializers.SerializerMethodField()

    def get_path(self, instance):
        reverse_view = reverse(viewname="todo-detail", args=[instance.pk])
        request = self.context.get('request', None)
        if request is not None:
            return request.build_absolute_uri(reverse_view)
        return reverse_view

views.py

class TodoListView(generics.ListAPIView):

    view_name = 'todo-list'
    serializer_class = TodoListSerializer
    permission_classes = ()

    def get_queryset(self):
        priority = self.request.query_params.get('priority', None)
        qs = self.request.user.todos.starting_from_today()

        if priority is not None:
            return qs.specific(priority=priority)
        return qs

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())

        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(queryset, many=True)
        data = {}
        data['priorities'] = {
            p[0].lower(): '{}?priority={}'.format(self.request.build_absolute_uri(reverse(viewname=self.view_name)), p[0] ) for p in TODO_PRIORITY
        }
        data['todos'] = serializer.data

        return Response(data)

OUTPUT OF TodoQueryset().__init__() print statement

System check identified no issues (0 silenced).
April 10, 2020 - 16:25:06
Django version 3.0.4, using settings 'config.sandbox'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
         weird 0
         weird 0
         weird 0
[10/Apr/2020 16:35:31] "GET /api/todos/ HTTP/1.1" 200 6377

at the moment i only have 1 Todo created, i kind of don't understand why it gets executed 3 times ( it gets executed 5 times on /api/todos/1/)

Anyone willing to shine some light into the matter ?

0

There are 0 answers