title: What exactly is the "QuerySet" object in Mongoengine?
body: <p>According to the Mongoengine API guide (<a href="http://mongoengine-odm.readthedocs.org/en/latest/apireference.html" rel="nofollow noreferrer">http://mongoengine-odm.readthedocs.org/en/latest/apireference.html</a>):</p>
  
  <pre><code>class mongoengine.queryset.QuerySet(document, collection)
  </code></pre>
  
  <p>is "<em>a set of results returned from a query. Wraps a MongoDB cursor, providing Document objects as the results.</em>"</p>
  
  <p>When I inspect the QuerySet object using <code>type()</code> in my interpreter, it says that the QuerySet object is a <code>&lt;class 'mongoengine.queryset.QuerySet'&gt;</code>, in agreement with the API guide.  </p>
  
  <p>I'm confused though because in order to actually access the individual Mongoengine <code>Document</code> objects in the QuerySet instance, I have to use index methods like [0] (for the first <code>Document</code>object) or [2] (for the third <code>Document</code> object) <a href="https://stackoverflow.com/questions/5990026/mongoengine-slicing-queryset-mongodb-with-django">See this SO question about slicing a QuerySet</a>.  Interestingly, you can also call <code>len()</code> on a QuerySet instance.  </p>
  
  <p><strong>Even though QuerySet is a class object, why does it seem to behave like a list object?  As far as I can tell, it doesn't inherit from <code>UserList</code> and doesn't have a <code>data</code> attribute.  Any help would be greatly appreciated.</strong></p>
  
  <p>Thanks.</p>
  
  <p><strong>EDIT:</strong></p>
  
  <p>Thanks for your suggestion @isbadawi.  That is helpful.  The QuerySet class object does indeed contain the <code>__getitem__</code> method which, as your link suggests, is "roughly equivalent" to indexing (e.g. <code>x.__getitem__(i)</code> is roughly equivalent to <code>x[i]</code>).  So if QuerySet is emulating a list class through <code>__getitem__</code>, where are the actual <code>Document</code> objects being stored in the class?  In an attribute?  This is the output of <code>dir(QuerySet)</code> in my interpreter:</p>
  
  <pre><code>&gt; ['_QuerySet__already_indexed', '_QuerySet__dereference', '__call__', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__getitem__', '__hash__', '__init__', '__iter__', '__len__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_as_pymongo', '_as_pymongo_coerce', '_build_index_spec', '_class_check', '_collection', '_collection_obj', '_cursor', '_cursor_args', '_cursor_obj', '_dereference', '_document', '_ensure_indexes', '_fields_to_dbfields', '_get_as_pymongo', '_get_scalar', '_hint', '_initial_query', '_item_frequencies_exec_js', '_item_frequencies_map_reduce', '_iter', '_limit', '_loaded_fields', '_lookup_field', '_mongo_query', '_ordering', '_query', '_query_obj', '_reset_already_indexed', '_scalar', '_skip', '_slave_okay', '_snapshot', '_sub_js_fields', '_timeout', '_transform_query', '_transform_update', '_translate_field_name', '_where_clause', 'all', 'all_fields', 'as_pymongo', 'average', 'clone', 'count', 'create', 'delete', 'distinct', 'ensure_index', 'exclude', 'exec_js', 'explain', 'fields', 'filter', 'first', 'get', 'get_or_create', 'hint', 'in_bulk', 'insert', 'item_frequencies', 'limit', 'map_reduce', 'next', 'only', 'order_by', 'rewind', 'scalar', 'select_related', 'skip', 'slave_okay', 'snapshot', 'sum', 'timeout', 'update', 'update_one', 'values_list', 'where', 'with_id']
  </code></pre>