docs: def build_query(spec):
      """ build the where clause based on a view specification
  
      spec -- The view specification. Contains the following possible values:
          future -- Boolean; whether to include entries from the future
          category -- Which category to limit to
          recurse -- Whether to include subcategories
          entry_type -- one or more entry types to include
          entry_type_not -- one or more entry types to exclude
          date -- a date spec
          last -- the last entry to end a view on
          first -- the first entry to start a view on
          before -- get entries from before this one
          after -- get entries from after this one
      """
  
      query = model.Entry.select()
  
      # primarily restrict by publication status
      if spec.get('_deleted', False):
          query = where_entry_deleted(query)
      elif spec.get('future', False):
          query = where_entry_visible_future(query)
      else:
          query = where_entry_visible(query)
  
      # restrict by category
      if spec.get('category') is not None:
          path = str(spec.get('category', ''))
          recurse = spec.get('recurse', False)
          query = where_entry_category(query, path, recurse)
  
      if spec.get('entry_type') is not None:
          query = where_entry_type(query, spec['entry_type'])
  
      if spec.get('entry_type_not') is not None:
          query = where_entry_type_not(query, spec['entry_type_not'])
  
      if spec.get('tag') is not None:
          query = where_entry_tag(query, spec['tag'])
  
      if spec.get('date') is not None:
          query = where_entry_date(query, spec['date'])
  
      if spec.get('last') is not None:
          query = where_entry_last(query, get_entry(spec['last']))
  
      if spec.get('first') is not None:
          query = where_entry_first(query, get_entry(spec['first']))
  
      if spec.get('before') is not None:
          query = where_before_entry(query, get_entry(spec['before']))
  
      if spec.get('after') is not None:
          query = where_after_entry(query, get_entry(spec['after']))
  
      return query.distinct()