
    h                        d dl Z d dlZd dlZd dlmZ d dlZd dlmZmZm	Z	m
Z
 d dlmZ d dlmZ d dlmZmZmZmZmZ d dlmZ d dlmZ d d	lmZmZmZmZmZ d d
lm Z  dZ!dZ"	 ejF                  Z# G d d      Z%y# e$$ r dZ#Y w xY w)    N)partial)SONDBRefObjectId	json_util)signals)get_document)BaseDictBaseListEmbeddedDocumentListLazyReference
StrictDict)ComplexBaseField_import_class)FieldDoesNotExistInvalidDocumentErrorLookUpErrorOperationErrorValidationError)LEGACY_JSON_OPTIONS)BaseDocumentNON_FIELD_ERRORS__all__c                       e Zd ZdZdZdZdZd Z fdZ fdZ	d Z
d Zd	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd)dZd*dZd Zed+d       Zd Zd Zd Zed        Z ed        Z!d Z"d Z#ed        Z$ed,d        Z%ed!        Z&ed"        Z'ed-d#       Z(ed.d$       Z)ed%        Z*ed/d&       Z+d' Z,d( Z- xZ.S )0r   )_changed_fields_initialised_created_data_dynamic_fields_auto_id_field_db_field_map__weakref__FTc                 r   d| _         d| _        |rt        d      |j                  dd      }|j                  dd      }t        j
                  j                  | j                  | |       | j                  s| j                  j                  dd      s|rkt        |j                               t        t        | j                  j                               g dz         z
  }|rd	| d
| j                   d}t!        |      | j"                  r7| j                  s+ t%        j&                  | j(                               | _        ni | _        t-               | _        | j                  D ]!  }||v rt1        | |d      }t3        | ||       # d|vr| j                  | _        i }	t7        d      }
|j9                         D ]x  \  }}| j                  j                  |      }|s|dv r1|r!||rt;        ||
      s|j=                  |      }t3        | ||       X| j                  r||	|<   j|| j*                  |<   z | j?                          | j                  r,d| _         |	j9                         D ]  \  }}t3        | ||        d| _         || _        t        jB                  j                  | j                  |        y)a   
        Initialise a document or an embedded document.

        :param values: A dictionary of keys and values for the document.
            It may contain additional reserved keywords, e.g. "__auto_convert".
        :param __auto_convert: If True, supplied values will be converted
            to Python-type values via each field's `to_python` method.
        :param _created: Indicates whether this is a brand new document
            or whether it's already been persisted before. Defaults to true.
        FTzuInstantiating a document with positional arguments is not supported. Please use `field_name=value` keyword arguments.__auto_convertr   )documentvaluesstrict)idpk_cls_text_scorezThe fields "z " do not exist on the document "")allowed_keysNr+   	FileField)r)   r*   r+   )r&   )"r   r   	TypeErrorpopr   pre_initsend	__class___dynamic_metagetsetkeyslist_fields_class_namer   STRICTr   create_fields_orderedr   r   r    getattrsetattrr+   r   items
isinstance	to_python _BaseDocument__set_field_display_dynamic_lock	post_init)selfargsr'   _BaseDocument__auto_convertr   _undefined_fieldsmsg
field_namevaluedynamic_datar/   keyfields                W/var/www/html/eduruby.in/venv/lib/python3.12/site-packages/mongoengine/base/document.py__init__zBaseDocument.__init__A   s    "N 
  $4d;::j$/dnntFK }}$**..4"@H #FKKM 2ST\\&&(),OO6 ! !$%6$77WX\XhXhWiijk',,;;t}}M**8L8LMODJDJ"u ,, 	-JV#D*d3ED*e,		- ((DI !+.	 ,,. 	,JCLL$$S)E33!e&7Zy%A % 6c5)==(-L% ',DJJsO	, 	  "==!&D*002 *
Uc5)* ! t~~=    c                     |d   }|| j                   v r9| j                   |   j                  }t        |      r |       }t        | ||       yt	        |   |i | y)zHandle deletions of fieldsr   N)r;   defaultcallablerA   super__delattr__)rH   rI   kwargsrM   rV   r4   s        rR   rY   zBaseDocument.__delattr__   sY    !W
%ll:.66G !)D*g.G00rT   c                    | j                   r| j                  s|| j                  vrR|j                  d      sAt	        d      } ||d      }||_        || j                  |<   | xj                  |fz  c_        |j                  d      s| j                  ||      }|| j                  v r,|| j                  |<   t        | d      r| j                  |       	 | j                  }| j                  rV|sT|| j                  j                  dt!                     v r.| j                  j                  |      |k7  rd|z  }t#        |      	 | j$                  }| j                  r2|r0|r.|| j                  j                  d	      k(  rt&        | Q  d
d       t&        | Q  ||       y # t        $ r d}Y w xY w# t        $ r d}Y mw xY w)N_DynamicFieldT)db_fieldnullr   	shard_keyz,Shard Keys are immutable. Tried to update %sFid_fieldr   )r5   rF   r?   
startswithr   namer    $_BaseDocument__expand_dynamic_valuesr   hasattr_mark_as_changedr   AttributeError_is_documentr6   r7   tupler   r   rX   __setattr__)	rH   rc   rN   r]   rQ   self__createdrL   self__initialisedr4   s	           rR   rj   zBaseDocument.__setattr__   s   ==!3!34///8L,^<$d>!
-2$$T*$$/$??3'44T5A t+++#(

4 4!23))$/	! MMM
 !

{EG<<

t$-@4GC %%	& $ 1 1 !

z22G
E2D%(5  	! M	!  	& %	&s$   F" F3 "F0/F03G Gc                 v    i }dD ]  }t        | |      st        | |      ||<     | j                         |d<   |S )N)r   r   r   r    r?   r   )re   r@   to_mongo)rH   dataks      rR   __getstate__zBaseDocument.__getstate__   sJ    
 	+A tQ!$*Q	+ WrT   c                    t        |d   t              r+| j                  j                  |d         j                  |d<   dD ]  }||v st        | |||           d|v r3| j                  r|d   | _        nt        |       j                  }|| _        |j                  d      xs
 t               }|j                         D ]!  }t        | ||d   j                  |             # y )Nr   )r   r   r   r   r    r?   r    )rC   r   r4   	_from_sonr   rA   r5   r?   typer7   r9   )rH   ro   rp   _super_fields_ordereddynamic_fieldss        rR   __setstate__zBaseDocument.__setstate__   s    d7mS) NN44T']CIIDM
 	*A Dyaa)	* $}}'+,='>$(,T
(B(B%'<$"34=$$& 	3AD!T']..q12	3rT   c                 ,    t        | j                        S N)iterr?   rH   s    rR   __iter__zBaseDocument.__iter__   s    D(())rT   c                     	 || j                   v rt        | |      S 	 t        |      # t        $ r Y t        |      w xY w)zADictionary-style field access, return a field's value if present.)r?   r@   rg   KeyError)rH   rc   s     rR   __getitem__zBaseDocument.__getitem__   sQ    	t+++tT** , tn  	tn	s   ( 	>>c                 f    | j                   s|| j                  vrt        |      t        | ||      S )z3Dictionary-style field access, set a field's value.)r5   r;   r~   rA   )rH   rc   rN   s      rR   __setitem__zBaseDocument.__setitem__  s/     }}T\\!94. tT5))rT   c                 B    	 t        | |      }|d uS # t        $ r Y yw xY w)NF)r@   rg   )rH   rc   vals      rR   __contains__zBaseDocument.__contains__	  s/    	$%Cd?" 		s    	c                 ,    t        | j                        S ry   )lenr   r{   s    rR   __len__zBaseDocument.__len__  s    4::rT   c                     	 | j                         }|t        n
t	        |      } |d| j
                  j                   d| d      S # t        t        f$ r d}Y Iw xY w)Nz[Bad Unicode data]<z: >)__str__UnicodeEncodeErrorUnicodeDecodeErrorstrrt   r4   __name__)rH   u	repr_types      rR   __repr__zBaseDocument.__repr__  sd    	%A 9C$q'	1T^^445Rs!<== #$67 	%$A	%s   A AAc                 l    t        | d      r| j                         S d| j                  j                  z  S )N__unicode__z	%s object)re   r   r4   r   r{   s    rR   r   zBaseDocument.__str__  s0    4'##%%T^^4444rT   c                 B   t        || j                        r1t        |d      r%|j                  | j                  |j                  k(  S t        |t              r8| j                         |j                  k(  xr | j                  |j                  k(  S | j                  | |u S y)Nr)   F)rC   r4   re   r)   r   _get_collection_name
collectionrH   others     rR   __eq__zBaseDocument.__eq__!  s    udnn-t$$77ehh&&eU#))+u/?/??WDGGuxxDW 77?5= rT   c                 &    | j                  |       S ry   )r   r   s     rR   __ne__zBaseDocument.__ne__0  s    ;;u%%%rT   c                      y)aI  
        Hook for doing document level data cleaning (usually validation or assignment)
        before validation is run.

        Any ValidationError raised by this method will not be associated with
        a particular field; it will have a special-case association with the
        field defined by NON_FIELD_ERRORS.
        N r{   s    rR   cleanzBaseDocument.clean3  s     	rT   c                 R    d| j                   vrt        d      | j                   d   S )z0
        Get text score from text query
        r,   z7This document is not originally built from a text query)r   r   r{   s    rR   get_text_scorezBaseDocument.get_text_score>  s1    
 

*&I  zz-((rT   c                    |xs g }t               }d|d<   | j                  |d<   |D ch c]  }|j                  d      d    }}| D ]J  }|r||vr| j                  j	                  |d      }| j
                  j	                  |      }|'| j                  r| j                  j	                  |      }||j                  j                  j                  }	i }
|r?d|	v r;d|z  }|D cg c]&  }|j                  |      s|j                  |d      ( }}||
d<   d	|	v r||
d	<    |j                  |fi |
}|+|j                  r|j                         }|| j                  |<   ||j                  s)|r|||j                   <   <|||j"                  <   M | j$                  j	                  d
      s|j'                  d       |S c c}w c c}w )z@
        Return as SON data ready for use with MongoDB.
        N_idr+   .r   fields%s. use_db_fieldallow_inheritance)r   r<   splitr   r7   r;   r5   r    rn   __code__co_varnamesrb   replace	_auto_gengenerater_   r^   rc   r6   r1   )rH   r   r   ro   froot_fieldsrM   rN   rQ   f_inputsex_varsrP   iembedded_fieldss                 rR   rn   zBaseDocument.to_mongoJ  s    2uU''V 1771qwws|A77 #	-Jz<JJNN:t4ELL$$Z0E},,00<  >>22>>h(2*,C4:'/0all3>O		#r*'O ' )8GH%!X-.:GN+&u88 }().

:& EJJ+0D(',D$G#	-L zz~~12HHVW 8"'s   G&G	=G	c           	         i }|r	 | j                          | j                  D cg c]R  }| j                  j                  || j                  j                  |            | j                  j                  |      fT }}t        d      }t        d      }|D ]{  \  }}	|	5	 t        |||f      r|j                  |	|       n|j                  |	       =|j                   sJt#        |dd      rXt        d|j                        ||j                  <   } |rsd	}
t%        | d
      r| j&                  }
n8| j(                  r,t%        | j(                  d
      r| j(                  j&                  }
d| j*                   d|
 d}t        ||      y# t        $ r}||t        <   Y d}~d}~ww xY wc c}w # t        $ r(}|j                  xs |||j                  <   Y d}~Ed}~wt        t        t        f$ r}|||j                  <   Y d}~qd}~ww xY w)zEnsure that all fields' values are valid and that required fields
        are present.

        Raises :class:`ValidationError` if any of the fields' values are found
        to be invalid.
        NEmbeddedDocumentFieldGenericEmbeddedDocumentField)r   r   FzField is required)rM   Noner*   zValidationError (:z) )errors)r   r   r   r?   r;   r7   r    r   r   rC   	_validater   rc   
ValueErrorrg   AssertionErrorrequiredr@   re   r*   	_instancer<   )rH   r   r   errorrc   r   r   r   rQ   rN   r*   messages               rR   validatezBaseDocument.validate  s    1

 ,,

    t';';'?'?'EF

t$
 
 !..E F'45S'T$" 	LE5 
/! 57ST U;.
 {E(J%4'EJJ&uzz"	$ BtT"WWGDNND$A^^&&)$*:*:);1RDCG!'&99 C # 1+0'(1
( ' ?).)>F5::&"NNC /).F5::&/sA   F	 AF)3F.		F&	F!!F&.	H7GH1HHc                     |j                  dd      }d|vr#t        j                  dt               t        |d<   t        j                  | j                  |      g|i |S )zConvert this document to JSON.

        :param use_db_field: Serialize field names as they appear in
            MongoDB (as opposed to attribute names on this document).
            Defaults to True.
        r   Tjson_options  No 'json_options' are specified! Falling back to LEGACY_JSON_OPTIONS with uuid_representation=PYTHON_LEGACY. For use with other MongoDB drivers specify the UUID representation to use. This will be changed to uuid_representation=UNSPECIFIED in a future release.)r1   warningswarnDeprecationWarningr   r   dumpsrn   )rH   rI   rZ   r   s       rR   to_jsonzBaseDocument.to_json  sa     zz.$7'MMG
 # &9F>"t}}\:LTLVLLrT   c                     d|vr#t        j                  dt               t        |d<   | j	                  t        j                  |fi ||      S )a  Converts json data to a Document instance

        :param str json_data: The json data to load into the Document
        :param bool created: Boolean defining whether to consider the newly
            instantiated document as brand new or as persisted already:
            * If True, consider the document as brand new, no matter what data
              it's loaded with (i.e. even if an ID is loaded).
            * If False and an ID is NOT provided, consider the document as
              brand new.
            * If False and an ID is provided, assume that the object has
              already been persisted (this has an impact on the subsequent
              call to .save()).
            * Defaults to ``False``.
        r   r   )created)r   r   r   r   rs   r   loads)cls	json_datar   rZ   s       rR   	from_jsonzBaseDocument.from_json  sP    & 'MMG
 # &9F>"}}Y__YA&A7}SSrT   c           	      z   t        |t        t        t        f      s|S t        |t              }|rd|v rt	        |d         } |di |S |r4|j                         D ci c]  \  }}|| j                  ||       }}}n|D cg c]  }| j                  ||       }}t        d      }t        |t        t        f      rCt        |t              s3t        t        |       |      rt        || |      }|S t        || |      }|S t        |t              rt        |t              st        || |      }|S c c}}w c c}w )z:Expand any dynamic values to their correct types / values.r+   EmbeddedDocumentListFieldr   )rC   dictr:   ri   r	   rB   rd   r   r   
issubclassrt   r   r
   )rH   rc   rN   is_dictr   rp   vr   s           rR   __expand_dynamic_valuesz$BaseDocument.__expand_dynamic_values  s,   %$e!45L UD)vuV}-C<<GL{{}Utq!Q44Q::UEUDIJqT11$:JEJ %22M$N!edE]+Juh4O$t*&?@,UD$? 	 !d3  t$Zx-HUD$/E VJs   D2D8c                    t        | d      syd|v r9|j                  dd      \  }}| j                  j                  ||      }| d| }n| j                  j                  ||      }|| j                  vr|j                  d      d}}|t        |      k  r5dj                  |d|       | j                  v ry|dz  }|t        |      k  r5| j                  j                  |       dj                  |d|       dz   }| j                  j                  }| j                  dd D ]  }|j                  |      s ||        yy)z-Mark a key as explicitly changed by the user.r   Nr      )
re   r   r"   r7   r   r   joinappendremoverb   )rH   rP   restlevelsidxlevelr   rQ   s           rR   rf   zBaseDocument._mark_as_changed  s@   t./#:		#q)IC$$((c2CE4&/C$$((c2Cd***))C.!CFV$88F4CL)T-A-AAq V$
 $$++C0.4--44!11!4 &E''.u& +rT   c                    t        d      }t        d      }| j                         D ]  }|j                  d      }| }|D ]  }t        |t              r	 |t        |         }nLt        |t              r|j                  |d      }n)|j                  j                  ||      }t        ||d      }t        |t              s"t        |d      rt        |dd      rg |_        t        |t        t        t        f      st        |d      rt        |j                  ||f      rt         j#                  |         g | _        y# t        $ r d}Y w xY w)	zdUsing _get_changed_fields iterate and remove any fields that
        are marked as changed.
        ReferenceFieldGenericReferenceFieldr   Nr   rh   FrQ   )r   _get_changed_fieldsr   rC   r:   int
IndexErrorr   r7   _reverse_db_field_mapr@   r   re   r   ri   rQ   r   $_nestable_types_clear_changed_fields)rH   r   r   changedpartsro   partrM   s           rR   _clear_changed_fieldsz"BaseDocument._clear_changed_fields"  sK    ''78 -.E F//1 	LGMM#&ED LdD)$#CI  d+88D$/D!%!;!;!?!?d!KJ"4T:D!$67+< t^U; +-D(tUD&9:tW-*

^5J$K3 ! EEdK1L	L:  "- & $#$s   EEEc                 2   t        d      }t        | d      st        |       }n| j                         }|D ]_  \  }}t        |d      rt	        ||      s|j                          /t	        |t        t        t        f      sKt        j                  |       a y)zaInspect nested data for changed fields

        :param data: data to inspect for changes
        DocumentrB   r   N)r   re   	enumeraterB   rC   r   r:   ri   r   r   r   )ro   r   iterator_index_or_keyrN   s        rR   r   z1BaseDocument._nestable_types_clear_changed_fieldsH  s     !, tW% Hzz|H$, 	I M5u34Zx> ++-ED%#67AA%H	IrT   c                 d   t        |d      st        |      }n|j                         }|D ]~  \  }}| | d}|dd | v rt        |d      r+|j                         }| |D cg c]  }|s| |  c}z  } Lt	        |t
        t        t        f      sht        j                  | ||        yc c}w )zInspect nested data for changed fields

        :param changed_fields: Previously collected changed fields
        :param base_key: The base key that must be used to prepend changes to this data
        :param data: data to inspect for changes
        rB   r   Nr   )
re   r   rB   r   rC   r:   ri   r   r   _nestable_types_changed_fields)	changed_fieldsbase_keyro   r   index_or_keyrN   item_keyr   rp   s	            rR   r   z+BaseDocument._nestable_types_changed_fields_  s     tW% Hzz|H#+ 	L%"L>3H }.u34335W"JhZs#3"JJED%#67;;"He	 #Ks   !B-)B-c                 L   t        d      }t        d      }t        d      }t        d      }t        d      }t        d      }g }|t        | dg       z  }| j                  D ]9  }| j                  j	                  ||      }	d|	z  }
| j
                  j	                  |d	      }| j                  j	                  |      |	|v rat        |      rnt        ||      r+|j                         }||D cg c]  }|s|
 |  c}z  }t        |t        t        t        f      st        d
      rt        j                  ||||f      rt        |      r3j                  r't        fd|D              r|j!                  |	       '| j#                  ||
|       < |S c c}w )z>Return a list of all fields that have explicitly been changed.EmbeddedDocumentLazyReferenceFieldr   GenericLazyReferenceFieldr   SortedListFieldr   r   NrQ   c              3   N   K   | ]  }j                   |j                  v   y wry   )	_orderingr   ).0drQ   s     rR   	<genexpr>z3BaseDocument._get_changed_fields.<locals>.<genexpr>  s      NA5??a.?.??Ns   "%)r   r@   r?   r"   r7   r   r;   rC   r   r:   ri   r   re   rQ   r   anyr   r   )rH   r   r   r   r   r   r   r   rM   db_field_namerP   ro   r   rp   rQ   s                 @rR   r   z BaseDocument._get_changed_fields}  s   ();<*+?@&'78$12M$N! -.E F'(9:'$(92>>.. "	OJ ..22:zJM-'C::>>*d3DLL$$Z0E.%0$ 01224"E11cU1#;"EED4"565'*zKK*&1-	0 7EOONNN&--m< 33NCNE"	OF ' #Fs   1F!9F!c                    | j                         }| j                         }i }t        | d      ri }|D ]  }|j                  d      }|}g }|D ]w  }	t	        |t
        t        f      r n_t	        |t              r|	j                         r|t        |	         }nt        |d      r|j                  |	      }|j                  |	       y dj                  |      }|||<    n	|}d|v r|d= t        |j                               D ]  \  }}
|
s t	        |
t        j                  t         f      r*|j                  d      }| j"                  r%t%        |      r|d   | j&                  v r	||= d||<   ld}|| j(                  v r| j(                  |   j*                  }n| }|j-                         }|D ]  }	t	        |t              r|	j                         r|t        |	         }2t        |d      r9t	        |t.              s)|j0                  j                  |	|	      }t3        ||      }w|j                  |	      } t        |d	      rR|j0                  j                  ||      }||j(                  v r&|j(                  j                  |      j*                  }nd}|t5        |      r |       n|}|
|k7  r||= d||<    ||fS )
zReturns the delta (set, unset) of the changes for a document.
        Gets any values that have been explicitly changed.
        r   r   r7   r   r   r   N__getattribute__r;   )rn   r   re   r   rC   r   r   r:   isdigitr   r7   r   r   rB   numbersNumberboolr5   r   r    r;   rV   r1   r   r   r@   rW   )rH   doc
set_fields
unset_dataset_datapathr   r  new_pathprN   rV   r  	real_pathrM   s                  rR   _deltazBaseDocument._delta  s   
 mmo--/

4*+H" #

3 
'A!!h%67#At,c!fI E*EE!HOOA&
' xx)!"!#$ H UO   01 -	!KD%
- JJsOE}}UaD<P<P0PTN#$
4  Gt||#,,t,44 %		 %A!!T*qyy{c!fI $67
1d@S$%$;$;$?$?1$E	#Ay1EE!H% 1i(!"!8!8!<!<%}"J "QYY."#))--
";"C"C"&"'/'8')g Jt[-	!\ ##rT   c                 :    | j                   j                  dd      S )zTReturn the collection name for this class. None for abstract
        class.
        r   N)r6   r7   )r   s    rR   r   z!BaseDocument._get_collection_name  s    
 yy}}\400rT   c           
      N   |r't        |t              st        dt        |      z        |j	                  d| j
                        }i }|j                         D ]1  \  }}t        |      }| j                  j	                  ||      }|||<   3 || j
                  k7  rt        |      } i }| j                  }	|st        j                  |	      }	|	j                         D ]_  \  }
}||_        |j                  |v s||j                     }	 ||n|j                  |      ||
<   |
|j                  k7  r||j                  = a |r_dj#                  |j                         D cg c]  \  }}d| d|  c}}      }dj%                  | j
                  |      }t'        |      | j(                  r2|j                         D ci c]  \  }}|| j                  v s|| }}} | d
d|d	|}g |_        |s|	|_
        |S # t         t        f$ r}|||
<   Y d}~8d}~ww xY wc c}}w c c}}w )zECreate an instance of a Document (subclass) from a PyMongo SON (dict)zEThe source SON object needs to be of type 'dict' but a '%s' was foundr+   N
zField 'z' - z*Invalid data to create a `{}` instance.
{}F)r%   r   r   )rC   r   r   rt   r7   r<   rB   r   r"   r	   r;   copydeepcopy_auto_dereferencer^   rD   rg   r   formatr   r=   r   )r   sonr  r   
class_namero   rP   rN   errors_dictr   rM   rQ   erp   r   r   rL   objs                     rR   rs   zBaseDocument._from_son  s&    z#t,Ws)  WWVS__5
 ))+ 	JCc(C##''S1CDI	 (z*C ]]6*F!' 	0J&7E#~~%U^^,0!&EOOE4J $ "U^^3 0	0 YYARARATUA'!D 4UVF?FFC 's++ ::%)ZZ\FTQQ#++5EAqDFDFAADA   CK
) '
3 0./K
+0  V Gs*   4G9H
=H!H!9HHHc                     | j                         }| j                         }|D cg c]  }| j                  |       }}d } |||      } |||      }|S c c}w )z(Generate and merge the full index specs.c                     |s| S | D ci c]  }t        |d         | }}|D ]D  }|j                  t        |d               }|| j                  |       4|j                  |       F | S c c}w )z&Helper method for merging index specs.r   )ri   r7   r   update)index_specsindicesindexspec_fields	new_index	candidates         rR   merge_index_specsz:BaseDocument._build_index_specs.<locals>.merge_index_specsP  s    "" GRRU5x158RKR
 % 0	'OOE)H2E,FG	$&&y1$$Y/0  Ss   A,)_geo_indices_unique_with_indexes_build_index_spec)r   meta_indexesgeo_indicesunique_indicesspecr$  r*  s          rR   _build_index_specszBaseDocument._build_index_specsI  si     &&(113?KLts,,T2LL	, ([A'^D5 Ms   Ac                    t        |t              rd|gi}n?t        |t        t        f      rdt        |      i}nt        |t              rt	        |      }g }d}| j
                  j                  d      }|xr0 |j                  dd       xr |j                  dd      xr d|d   v}|xr0 |j                  dd      xs | j
                  j                  d	d      }d|v r|j                  d       |d   D ]  }t        |t        t        f      rt        j                  }|j                  d
      rt        j                  }n|j                  d      rt        j                  }n|j                  d      rt        j                  }nf|j                  d      rt        j                  }nD|j                  d      r	 t        j                  }n!|j                  d      rt        j$                  }|j                  d      r|dd }|j'                  d      }|dgdgdgfv rd}nN| j)                  |      }g }|D ]%  }		 |	dk7  r|	j*                  }	|j-                  |	       ' dj/                  |      }|j-                  ||f        |rC|t        j$                  t        j                  fvr!t        	|t        k7  r|j1                  dd       |r||d<   |S # t         $ r t"        w xY w# t         $ r Y w xY w)z9Build a PyMongo index spec from a MongoEngine index spec.r   Nr   sparseFr   Tr+   	index_cls-$#()*)+r6  r;  r7  r8  r9  r:  r   r   r*   r)   r   r   )r+   r   )rC   r   r:   ri   r   r6   r7   r1   pymongo	ASCENDINGrb   
DESCENDINGTEXTHASHED	GEOSPHEREGEOHAYSTACKrg   NotImplementedErrorGEO2Dr   _lookup_fieldr^   r   r   insert)
r   r1  
index_list	directionr   include_clsrP   r   r   rQ   s
             rR   r-  zBaseDocument._build_index_specj  s    dC tf%DtUm,d4j)Dd#:D
	  IIMM*=> -HHXu---%- d8n,	 	 " 
HHUE"FciimmK&F 	 D=HHUO> /	0C#e}-  ))I~~c"#..	$#LL	$#NN	$#--	$. ' 3 3I $#MM	~~AB!"g IIcNE$$%11**51# (E E>$)NNE LL'( hhuosI./_/	0f '--1B1B!CC$	[(@a-'DNI & .--.& * s   <K;K'K$'	K32K3c                    g }| j                   j                         D ]  \  }}|j                  }|j                  r|j                  g}|j
                  rt        |j
                  t              r|j
                  g|_        g }|j
                  D ]  }|j                  d      }	| j                  |	      }	|	D 
cg c]  }
|
j                   }}
|j                  dj                  |             d|	d   _        | xr |	d   j                  | j                  v} ||z  }|D cg c]  }| | t        j                   f }}|d|d}|j                  |       |j"                  j$                  dv r|j&                  }|j"                  j$                  dk(  s{|j(                  | k7  sd|z  }|j(                  }||j+                  |      z  } |S c c}
w c c}w )z;Find unique indexes in the document schema and return them.r   Tr   )r   uniquer4  >   	ListFieldr   r   r   r   )r;   rB   r4  rL  r^   unique_withrC   r   r   rF  r   r   r   rc   __dict__r=  r>  r4   r   rQ   document_typer,  )r   	namespaceunique_indexesrM   rQ   r4  unique_fieldsrN  
other_namer   r   
name_partsr   r   r&  field_namespacedoc_clss                    rR   r,  z!BaseDocument._unique_with_indexes  s    !$!2!2!4 /	PJ\\F ||!& 0 $$!%"3"3S9-2->->,?) #%K&+&7&7 
S
 * 0 0 5 !$ 1 1% 8@E%Fdmm%F
%F#**388J+?@ .2b	*%+!Rb	cll0R
S "[0M KXXQi[,g.?.?@XX#)TVL%%e,'' , 
  ((,CC''3."'*"4--'">">"OO_/	Pb = &G Ys   9G#Gc                    |xs g }g }|j                  |        d}t        d |D              }| j                  j                         D ]  }t	        ||      st        |d      r?|j                  }||v r-t        |d      s:||j                  ||j                        z  }[|j                  sh|j                  }|r| d| }|j                  d||j                  fgi        |S )N)r   GeoPointField
PointFieldLineStringFieldPolygonFieldc              3   2   K   | ]  }t        |        y wry   r   )r  rQ   s     rR   r  z,BaseDocument._geo_indices.<locals>.<genexpr>	  s     We 4Ws   rP  r+  )parent_fieldr   r   )
r   ri   r;   r'   rC   re   rP  r+  r^   
_geo_index)	r   	inspectedr^  r/  geo_field_type_namesgeo_field_typesrQ   	field_clsrM   s	            rR   r+  zBaseDocument._geo_indices  s   O	 
  WBVWW[['') 	QEe_5uo.!//		)9n59#9#9! $: $ K !!"^^
$0>:,!?J""H
E<L<L/M.N#OP#	Q& rT   c                 
   t        d      }t        d      }t        |t        t        f      s|g}g }d}|D ]9  }|j	                         rt        ||      r|j                  |       2||dk(  r| j                  d   }|| j                  v r| j                  |   }n| j                  r ||      }n| j                  j                  d      s| j                  j                  dd	      r>| j                         D ]  }	 |j                  |g      d
   }| nE t        d|z        t        d|z        t        d      }t        d      }	t        |||	f      rt        ddj                  |      z        t        t        |dd      d      r|j                   j#                  |      }
n}| j                  r.t        ||      st        t        |dd      dd      r
 ||      }
nCt        |d      r|j#                  |      }
n%t        dj%                  ||j&                              |
s#t        |t(              r|j                  |       |
st        d|z        |
}|j                  |       < |S # t        $ r Y w xY w)a  Given the path to a given field, return a list containing
        the Field object associated with that field and all of its parent
        Field objects.

        Args:
            parts (str, list, or tuple) - path to the field. Should be a
            string for simple fields existing on this document or a list
            of strings for a field that exists deeper in embedded documents.

        Returns:
            A list of Field instances for fields that were found or
            strings for sub-fields that weren't.

        Example:
            >>> user._lookup_field('name')
            [<mongoengine.fields.StringField at 0x1119bff50>]

            >>> user._lookup_field('roles')
            [<mongoengine.fields.EmbeddedDocumentListField at 0x1119ec250>]

            >>> user._lookup_field(['roles', 'role'])
            [<mongoengine.fields.EmbeddedDocumentListField at 0x1119ec250>,
             <mongoengine.fields.StringField at 0x1119ec050>]

            >>> user._lookup_field('doesnt_exist')
            raises LookUpError

            >>> user._lookup_field(['roles', 'doesnt_exist'])
            [<mongoengine.fields.EmbeddedDocumentListField at 0x1119ec250>,
             'doesnt_exist']

        rM  r]   Nr*   ra   )r^   r   abstractFr   zCannot resolve field "%s"r   r   z"Cannot perform join in mongoDB: %s__rQ   lookup_memberrP  r5   z6Cannot resolve subfield or operator {} on the field {})r   rC   r:   ri   r  r   r6   r;   r5   r7   __subclasses__rF  r   r   re   r@   rQ   rg  r  rc   r   )r   r   rM  r]   r   rQ   rM   subclsr   r   	new_fields              rR   rF  zBaseDocument._lookup_field   s   J "+.	$^4%$/GE Q	!J!!#
5)(Dj) }%!$:!6J,KK
3E\\(*=EYY]]#67399==< #&"4"4"6 	T%$*$8$8*$Fq$IE !,!	T **E
*RSS%&AJ&NOO!./?!@(56M(N% en6K%LM%<tyy?OO  75'48/J % 9 9* EI
 \\ul3wuotDjRVW ,j AI UO4 % 3 3J ?I &**0&UZZ*H  !Z7G%HMM*-"%&AJ&NOO!MM% cQ	!f y  + %$%s   ?I55	JJc                     |j                  |      }| j                  |      D cg c]  }|j                   }}dj                  |      S c c}w )z:Translate a field attribute name to a database field name.r   )r   rF  r^   r   )r   rQ   sepr   r   s        rR   _translate_field_namez"BaseDocument._translate_field_name  sG     C %(%6%6u%=>>>xx ?s   Ac           	          | j                   j                         D cg c]  \  }}|j                  s||f }}}|D ]*  \  }}t        | d|z  t	        | j
                  |             , yc c}}w )z\For each field that specifies choices, create a
        get_<field>_display method.
        zget_%s_display)rQ   N)r;   rB   choicesrA   r    _BaseDocument__get_field_display)rH   nr   fields_with_choices	attr_namerQ   s         rR   __set_field_displayz BaseDocument.__set_field_display  sp     37,,2D2D2FT$!Q!))1vTT 3 	Iu 9,00>	 Us
   A,A,c                    t        | |j                        }|j                  rt        |j                  d   t        t
        f      r||yt        |dd      }|j                  j                  dv r|n|g}|j                  |xs g D cg c]0  }t        t        |j                        j                  ||            2 c}      S |S c c}w )z+Return the display value for a choice fieldr   Ndisplay_sep )rM  r   )r@   rc   ro  rC   r:   ri   r4   r   r   r   r   r7   )rH   rQ   rN   rl  r'   r   s         rR   __get_field_displayz BaseDocument.__get_field_display  s    ejj)==Za(84-H}%4C ??++/OO W 
 88CI<RPCT%--(,,S#67P   Qs   5C)TN)T)F)TF)r   )NN)r   )/r   
__module____qualname__	__slots__r5   rF   r=   rS   rY   rj   rq   rw   r|   r   r   r   r   r   r   r   r   r   r   rn   r   r   classmethodr   rd   rf   r   staticmethodr   r   r   r  r   rs   r2  r-  r,  r+  rF  rm  rE   rp  __classcell__)r4   s   @rR   r   r   '   s   	I HMFS>j	1.)`3.**>5&	
)6p4:lM( T T<8&6$"L I I,  :/bQ$f 1 1 > >@  @ W Wr 4 4l " "H @ @D  
rT   r   )&r  r	  r   	functoolsr   r=  bsonr   r   r   r   mongoenginer   mongoengine.base.commonr	   mongoengine.base.datastructuresr
   r   r   r   r   mongoengine.base.fieldsr   mongoengine.commonr   mongoengine.errorsr   r   r   r   r   mongoengine.pymongo_supportr   r   r   rC  rg   r   r   rT   rR   <module>r     s~         0 0  0  5 ,  <
. %%K
^ ^	  Ks   "A9 9BB