Prefetcher container. One would directly use this when wanting to attach a custom QuerySet for specialised prefetching. :param relation: Related field name. :param queryset: Custom QuerySet to use for prefetching. :param to_attr: Sets the result of the prefetch operation to a c
| 231 | |
| 232 | |
| 233 | class Prefetch: |
| 234 | """ |
| 235 | Prefetcher container. One would directly use this when wanting to attach a custom QuerySet |
| 236 | for specialised prefetching. |
| 237 | |
| 238 | :param relation: Related field name. |
| 239 | :param queryset: Custom QuerySet to use for prefetching. |
| 240 | :param to_attr: Sets the result of the prefetch operation to a custom attribute. |
| 241 | """ |
| 242 | |
| 243 | __slots__ = ("relation", "queryset", "to_attr") |
| 244 | |
| 245 | def __init__(self, relation: str, queryset: QuerySet, to_attr: str | None = None) -> None: |
| 246 | self.to_attr = to_attr |
| 247 | self.relation = relation |
| 248 | self.queryset = queryset |
| 249 | self.queryset.query = copy(self.queryset.model._meta.basequery) |
| 250 | |
| 251 | def resolve_for_queryset(self, queryset: QuerySet) -> None: |
| 252 | """ |
| 253 | Called internally to generate prefetching query. |
| 254 | |
| 255 | :param queryset: Custom QuerySet to use for prefetching. |
| 256 | :raises OperationalError: If field does not exist in model. |
| 257 | """ |
| 258 | |
| 259 | first_level_field, __, forwarded_prefetch = self.relation.partition("__") |
| 260 | if first_level_field not in queryset.model._meta.fetch_fields: |
| 261 | raise OperationalError( |
| 262 | f"relation {first_level_field} for {queryset.model._meta.db_table} not found" |
| 263 | ) |
| 264 | |
| 265 | if forwarded_prefetch: |
| 266 | if first_level_field not in queryset._prefetch_map: |
| 267 | queryset._prefetch_map[first_level_field] = set() |
| 268 | queryset._prefetch_map[first_level_field].add( |
| 269 | Prefetch(forwarded_prefetch, self.queryset, to_attr=self.to_attr) |
| 270 | ) |
| 271 | else: |
| 272 | queryset._prefetch_queries.setdefault(first_level_field, []).append( |
| 273 | (self.to_attr, self.queryset) |
| 274 | ) |
| 275 | |
| 276 | |
| 277 | def get_json_filter_operator( |
no outgoing calls
searching dependent graphs…