mirror of
				https://github.com/graphql-python/graphene.git
				synced 2025-10-30 23:47:55 +03:00 
			
		
		
		
	Improved queryset getter for use .count instead of len
This commit is contained in:
		
							parent
							
								
									28414955a2
								
							
						
					
					
						commit
						ee19445290
					
				|  | @ -1,5 +1,8 @@ | ||||||
| from django.db import models | from django.db import models | ||||||
| from django.db.models.manager import Manager | from django.db.models.manager import Manager | ||||||
|  | from django.db.models.query import QuerySet | ||||||
|  | 
 | ||||||
|  | from graphene.utils import LazyList | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def get_type_for_model(schema, model): | def get_type_for_model(schema, model): | ||||||
|  | @ -19,7 +22,18 @@ def get_reverse_fields(model): | ||||||
|             yield related |             yield related | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | class WrappedQueryset(LazyList): | ||||||
|  | 
 | ||||||
|  |     def __len__(self): | ||||||
|  |         # Dont calculate the length using len(queryset), as this will | ||||||
|  |         # evaluate the whole queryset and return it's length. | ||||||
|  |         # Use .count() instead | ||||||
|  |         return self._origin.count() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| def maybe_queryset(value): | def maybe_queryset(value): | ||||||
|     if isinstance(value, Manager): |     if isinstance(value, Manager): | ||||||
|         value = value.get_queryset() |         value = value.get_queryset() | ||||||
|  |     if isinstance(value, QuerySet): | ||||||
|  |         return WrappedQueryset(value) | ||||||
|     return value |     return value | ||||||
|  |  | ||||||
|  | @ -4,6 +4,7 @@ from collections import Iterable | ||||||
| from functools import wraps | from functools import wraps | ||||||
| 
 | 
 | ||||||
| import six | import six | ||||||
|  | 
 | ||||||
| from graphql_relay.connection.arrayconnection import connection_from_list | from graphql_relay.connection.arrayconnection import connection_from_list | ||||||
| from graphql_relay.node.node import to_global_id | from graphql_relay.node.node import to_global_id | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -3,8 +3,9 @@ from .proxy_snake_dict import ProxySnakeDict | ||||||
| from .caching import cached_property, memoize | from .caching import cached_property, memoize | ||||||
| from .misc import enum_to_graphql_enum | from .misc import enum_to_graphql_enum | ||||||
| from .resolve_only_args import resolve_only_args | from .resolve_only_args import resolve_only_args | ||||||
|  | from .lazylist import LazyList | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| __all__ = ['to_camel_case', 'to_snake_case', 'ProxySnakeDict', | __all__ = ['to_camel_case', 'to_snake_case', 'ProxySnakeDict', | ||||||
|            'cached_property', 'memoize', 'enum_to_graphql_enum', |            'cached_property', 'memoize', 'enum_to_graphql_enum', | ||||||
|            'resolve_only_args'] |            'resolve_only_args', 'LazyList'] | ||||||
|  |  | ||||||
							
								
								
									
										43
									
								
								graphene/utils/lazylist.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								graphene/utils/lazylist.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,43 @@ | ||||||
|  | class LazyList(object): | ||||||
|  | 
 | ||||||
|  |     def __init__(self, origin, state=None): | ||||||
|  |         self._origin = origin | ||||||
|  |         self._state = state or [] | ||||||
|  |         self._origin_iter = None | ||||||
|  |         self._finished = False | ||||||
|  | 
 | ||||||
|  |     def __iter__(self): | ||||||
|  |         return self if not self._finished else iter(self._state) | ||||||
|  | 
 | ||||||
|  |     def iter(self): | ||||||
|  |         return self.__iter__() | ||||||
|  | 
 | ||||||
|  |     def __len__(self): | ||||||
|  |         return self._origin.__len__() | ||||||
|  | 
 | ||||||
|  |     def __next__(self): | ||||||
|  |         try: | ||||||
|  |             if not self._origin_iter: | ||||||
|  |                 self._origin_iter = self._origin.__iter__() | ||||||
|  |             n = next(self._origin_iter) | ||||||
|  |         except StopIteration as e: | ||||||
|  |             self._finished = True | ||||||
|  |             raise e | ||||||
|  |         else: | ||||||
|  |             self._state.append(n) | ||||||
|  |             return n | ||||||
|  | 
 | ||||||
|  |     def next(self): | ||||||
|  |         return self.__next__() | ||||||
|  | 
 | ||||||
|  |     def __getitem__(self, key): | ||||||
|  |         item = self._origin[key] | ||||||
|  |         if isinstance(key, slice): | ||||||
|  |             return self.__class__(item) | ||||||
|  |         return item | ||||||
|  | 
 | ||||||
|  |     def __getattr__(self, name): | ||||||
|  |         return getattr(self._origin, name) | ||||||
|  | 
 | ||||||
|  |     def __repr__(self): | ||||||
|  |         return "<{} {}>".format(self.__class__.__name__, repr(self._origin)) | ||||||
							
								
								
									
										23
									
								
								graphene/utils/tests/test_lazylist.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								graphene/utils/tests/test_lazylist.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,23 @@ | ||||||
|  | from py.test import raises | ||||||
|  | 
 | ||||||
|  | from ..lazylist import LazyList | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_lazymap(): | ||||||
|  |     data = list(range(10)) | ||||||
|  |     lm = LazyList(data) | ||||||
|  |     assert len(lm) == 10 | ||||||
|  |     assert lm[1] == 1 | ||||||
|  |     assert isinstance(lm[1:4], LazyList) | ||||||
|  |     assert lm.append == data.append | ||||||
|  |     assert repr(lm) == '<LazyList [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]>' | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_lazymap_iter(): | ||||||
|  |     data = list(range(2)) | ||||||
|  |     lm = LazyList(data) | ||||||
|  |     iter_lm = iter(lm) | ||||||
|  |     assert iter_lm.next() == 0 | ||||||
|  |     assert iter_lm.next() == 1 | ||||||
|  |     with raises(StopIteration): | ||||||
|  |         iter_lm.next() | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user