11import copy
2- import itertools
32import re
43from itertools import chain
5- from typing import List , Dict , Optional , Union , Tuple , Set
4+ from typing import Dict , Optional , Union , Tuple , Set
65
76from django .db .models import Prefetch
87from rest_framework .exceptions import ValidationError
98from rest_framework .generics import get_object_or_404
109from rest_framework .renderers import BrowsableAPIRenderer
1110from rest_framework .response import Response
12- from rest_framework .serializers import ListSerializer , ModelSerializer
11+ from rest_framework .serializers import ListSerializer
1312
1413from drf_sideloading .renderers import BrowsableAPIRendererWithoutForms
1514from drf_sideloading .serializers import SideLoadableSerializer
@@ -310,8 +309,6 @@ def get_sideloadable_page(
310309 """
311310 sideloadable_page = {primary_field_name : page }
312311 for relation , source_keys in relations_to_sideload .items ():
313-
314- # fixme: field.source can't be used in case prefetces with "to_attr" other than source is used
315312 field = sideloadable_fields [relation ]
316313 field_source = field .child .source
317314 relation_key = field_source or relation
@@ -322,12 +319,8 @@ def get_sideloadable_page(
322319 if relation not in sideloadable_page :
323320 sideloadable_page [relation_key ] = set ()
324321
325- # TODO: case when no or all keys are present, use the __all__ prefetch if present,
326- # else loop through all the relations.
327- # TODO: the correct field might be relation even if source is present
328- # Check this usage.
329-
330322 if isinstance (relations_sources .get (relation ), dict ):
323+ # Multi source relation
331324 for src_key , src in relations_sources [relation ].items ():
332325 if not (source_keys is None or src_key in source_keys or src_key == "__all__" ):
333326 raise ValueError (f"Unexpected relation source '{ src_key } ' used" )
@@ -385,8 +378,6 @@ def filter_related_objects(self, related_objects, lookup: Optional[str]) -> Set:
385378 getattr (r , current_lookup ) for r in related_objects if getattr (r , current_lookup , None ) is not None
386379 ]
387380
388- # TODO: make sure this follows the new logic (fetching from source or prefetch to_attr)
389-
390381 if lookup_values :
391382 if lookup_values [0 ].__class__ .__name__ in ["ManyRelatedManager" , "RelatedManager" ]:
392383 related_objects_set = set (chain (* [related_queryset .all () for related_queryset in lookup_values ]))
@@ -420,27 +411,19 @@ def _clean_prefetches(self, field, relation, value, ensure_list=False):
420411 f"Sideloadable field '{ relation } ' Prefetch 'to_attr' can't be used with source defined. "
421412 f"Remove source from field serializer."
422413 )
423- # if "queryset" not in prefetches:
424- # raise ValueError(f"Sideloadable field '{relation}' Prefetch 'queryset' must be set!")
425414 if value .get ("queryset" ) or value .get ("to_attr" ):
426415 if not value .get ("to_attr" ):
427416 value ["to_attr" ] = relation
428417 cleaned_value = Prefetch (** value )
429418 else :
430419 cleaned_value = value ["lookup" ]
431420 elif isinstance (value , Prefetch ):
432- # check that to_attr is set the same as the field!
433- # TODO: new method of fetching the values should not require this
421+ # check that Prefetch.to_attr is set the same as the field.source!
434422 if value .to_attr and field .child .source and field .child .source != value .to_attr :
435423 raise ValueError (
436424 f"Sideloadable field '{ relation } ' Prefetch 'to_attr' can't be different from source defined. "
437425 f"Tip: Remove source from field serializer."
438426 )
439- # if not value.to_attr:
440- # if value.prefetch_to != relation:
441- # raise ValueError(f"Sideloadable field '{relation}' Prefetch 'to_attr' must be set!")
442- # elif value.to_attr != relation:
443- # raise ValueError(f"Sideloadable field '{relation}' Prefetch 'to_attr' must match the field name!")
444427 cleaned_value = value
445428 else :
446429 raise ValueError ("Sideloadable prefetch values must be a list of strings or Prefetch objects" )
@@ -496,9 +479,6 @@ def _gather_all_prefetches(self, sideloadable_fields: Dict, user_defined_prefetc
496479 else :
497480 raise NotImplementedError (f"prefetch with type '{ type (user_prefetches )} ' is not implemented" )
498481
499- # TODO: check for Prefetch objects with the save 'to_attr'
500- # maybe it better to check this wihte requesting because it won't be an issue until they clash.
501-
502482 return cleaned_prefetches
503483
504484 def _add_prefetch (self , prefetches : Dict , prefetch : Union [str , Prefetch ]) -> str :
@@ -553,12 +533,6 @@ def _get_relevant_prefetches(
553533
554534 # gather prefetches and sources
555535 if relation_prefetches is None :
556- # TODO: check primary serializer model for direct source?
557- # else allow to fail with invalid prefetch
558- # prefetch_attr = self._add_prefetch(
559- # prefetches=gathered_prefetches, prefetch=sideloadable_fields[relation].child.source or relation
560- # )
561- # relations_sources[relation] = [prefetch_attr]
562536 raise ValueError (
563537 f"Missing prefetch for field '{ relation } '. Check '_gather_all_prefetches' works correctly"
564538 )
@@ -631,8 +605,8 @@ def _get_relevant_prefetches(
631605 f"source '{ invalid_source_key } ' has not been implemented for sideloadable field '{ relation } '"
632606 )
633607 elif "__all__" in relation_prefetches :
634- # TODO: find source in case it's not a Prefetch object.
635- requested_sources = [relation_prefetches ["__all__" ].to_attr ]
608+ # find source in case it's not a Prefetch object.
609+ # requested_sources = [relation_prefetches["__all__"].to_attr]
636610 raise NotImplementedError ("default prefetch for all in not implemented" )
637611 elif relation_prefetches :
638612 requested_sources = list (relation_prefetches .keys ())
0 commit comments