3
6b                 @   s  d Z ddlZddlZddlZddlmZ ddlmZ ddlm	Z	 ddl
mZ ddl
mZmZmZ ddlmZ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 ddlmZ ddlmZm Z  ddl!m"Z" ddl#m$Z% ddl&m'Z'm(Z( e)ej* j+dd Z,e,dkrddl-m.Z.m/Z/ dd Z0dd Z1G dd deZ2G dd deZ3G dd de3Z4G dd de3Z5G d d! d!e5Z6G d"d# d#e6Z7d$d% Z8G d&d' d'ej9j:Z;G d(d) d)ejZ<G d*d+ d+ej=Z>G d,d- d-ej?Z@G d.d/ d/e6ZAG d0d1 d1ejBZCG d2d3 d3ej=ZDG d4d5 d5ejEZFG d6d7 d7ZGG d8d9 d9eGeZHe,dkrbG d:d; d;e.eHe/d<ZInG d=d; d;eGeZIG d>d? d?eIZJG d@dA dAZKdBdC ZLdDdE ZMG dFdG dGZNG dHdI dIZOG dJdK dKeZPdS )La6  
The standard way of using djongo is to import models.py
in place of Django's standard models module.

Djongo Fields is where custom fields for working with
MongoDB is defined.

 - EmbeddedField
 - ArrayField
 - ArrayReferenceField
 - GenericReferenceField

These are the main fields for working with MongoDB.
    N)ObjectId)forms)ValidationError)connections)routerr   transaction)ManagerModelField	AutoField
ForeignKeyBigAutoField)version)RelatedField)modelform_factory)cached_property)format_html_joinformat_html)	mark_safe)gettext_lazy)NotSupportedError
print_warn.   )AutoFieldMixinAutoFieldMetac             C   s6   x*|D ]"}| j j|}|j|| ||< qW | f |S )z:
    Builds an instance of model from the model_dict.
    )_meta	get_field	to_python)modelZ
model_dict
field_namefield r"   S/var/www/html/sandeepIITI/myenv/lib/python3.6/site-packages/djongo/models/fields.pymake_mdl+   s    
r$   c             C   s   | j ot| ttf S )N)concrete
isinstancer   r   )r!   r"   r"   r#   useful_field6   s    r'   c                   s,   e Zd ZdZ fddZedd Z  ZS )DjongoManagerz
    This modified manager allows to issue Mongo functions by prefixing
    them with 'mongo_'.

    This module allows methods to be passed directly to pymongo.
    c                s2   |j dr"|dd  }t| j|S t j|S d S )NZmongo   )
startswithgetattr_clientsuper__getattr__)selfname)	__class__r"   r#   r.   B   s    
zDjongoManager.__getattr__c             C   s   t | j j j| jjj S )N)pymongo_connectionsdbcursorZdb_connr   r   Zdb_table)r/   r"   r"   r#   r,   I   s    zDjongoManager._client)__name__
__module____qualname____doc__r.   propertyr,   __classcell__r"   r"   )r1   r#   r(   :   s   r(   c               @   s   e Zd ZdZdS )
MongoFieldFN)r5   r6   r7   empty_strings_allowedr"   r"   r"   r#   r;   P   s   r;   c               @   s   e Zd Zdd Zdd ZdS )	JSONFieldc             C   s"   t |ttfstd| d|S )NzValue: z must be of type dict/list)r&   dictlist
ValueError)r/   valuer"   r"   r#   get_prep_valueU   s    zJSONField.get_prep_valuec             C   s"   t |ttfstd| d|S )NzValue: zC stored in DB must be of type dict/listDid you miss any Migrations?)r&   r>   r?   r@   )r/   rA   r"   r"   r#   r   \   s    zJSONField.to_pythonN)r5   r6   r7   rB   r   r"   r"   r"   r#   r=   T   s   r=   c                   s   e Zd ZdZeZeje d fddZ	dd Z
eeddd	Zeedd
dZeedddZdd Zd" fdd	Zdd Z fddZ fddZdd Zdd Zdd Zd d! Z  ZS )#
ModelFieldzh
    Allows for the inclusion of an instance of an abstract model as
    a field inside a document.
    )model_containerc                s    || _ | j  t j|| d S )N)rD   _validate_containerr-   __init__)r/   rD   argskwargs)r1   r"   r#   rF   l   s    zModelField.__init__c             C   s   x| j jjddD ]}t|tttfrHtd| d| j  dt| d|j	|j
kr|td| d| j  d|j	 d	|j
 d	|jrtd
 tdqW d S )NF)reversezField "z" of model container:"z" cannot be of type ""z"  of model container:"z" cannot be named as "z", different from column name "zEmbedded field indexzBThis version of djongo does not support indexes on embedded fields)rD   r   Z_get_fieldsr&   r   r   r   r   typeattnamecolumnZdb_indexr   r   )r/   r!   r"   r"   r#   rE   s   s     &zModelField._validate_container)	func_namerA   c             G   s^   i }xT| j jj D ]D}y||j }W n tk
r:   wY nX t|||f| ||j< qW |S )N)rD   r   
get_fieldsrL   KeyErrorr+   )r/   rN   rA   
other_argsprocessed_valuer!   field_valuer"   r"   r#   _value_thru_fields   s    zModelField._value_thru_fieldsc       	      G   s   i }i }x| j jj D ]}yRy||j }W n$ tk
rN   td| dY nX t|||f| ||j< W q tk
r } z|j||j< W Y d d }~X qX qW |rt|}tt	||S )NzValue for field "z" not supplied)
rD   r   rO   rL   rP   r   r+   Z
error_listr0   str)	r/   rN   rA   rQ   rR   errorsr!   rS   er"   r"   r#   _save_value_thru_fields   s    "z"ModelField._save_value_thru_fields)rN   objc             G   s8   i }x.| j jj D ]}t|||f| ||j< qW |S )N)rD   r   rO   r+   rL   )r/   rN   rY   rQ   rR   r!   r"   r"   r#   _obj_thru_fields   s    zModelField._obj_thru_fieldsc             C   s<   i }| j f |}x&| j jj D ]}t||j||j< qW |S )N)rD   r   rO   r+   rL   )r/   rA   rR   instr!   r"   r"   r#   _value_thru_container   s
    z ModelField._value_thru_containerTc                sJ   |rt  j|| |d kr,t  j|| d S | jf |}| jd|| d S )Nvalidate)r-   r]   rD   rT   )r/   rA   model_instancevalidate_parentZcontainer_instance)r1   r"   r#   r]      s    zModelField.validatec             C   sH   | j |}|d kr&tdt| d| jf |}| jd|}tj|S )NzType: z cannot be serializedvalue_to_string)value_from_object	TypeErrorrK   rD   rZ   jsondumps)r/   rY   rA   container_objrR   r"   r"   r#   r`      s    
zModelField.value_to_stringc                s4   t  j|}|d krd S | jf |}| jd|}|S )Nra   )r-   ra   rD   rZ   )r/   rY   rA   re   rR   )r1   r"   r#   ra      s    zModelField.value_from_objectc                s(   t  j \}}}}| j|d< ||||fS )NrD   )r-   deconstructrD   )r/   r0   pathrG   rH   )r1   r"   r#   rf      s    
zModelField.deconstructc             C   s@   |d krd S t || js.td| d| j | jd||}|S )NzValue: z must be an instance of get_db_prep_save)r&   	base_typer@   rX   )r/   rA   
connectionrR   r"   r"   r#   rh      s    zModelField.get_db_prep_savec             C   s*   |d kst || j r|S | jd|}|S )NrB   )r&   ri   rT   )r/   rA   rR   r"   r"   r#   rB      s    zModelField.get_prep_valuec             G   s
   | j |S )N)r   )r/   rA   rG   r"   r"   r#   from_db_value   s    zModelField.from_db_valuec             C   s\   |dkrdS t |tr tj|}t || jsBtd| d| j | j|}| jd|}|S )zh
        Overrides Django's default to_python to allow correct
        translation to instance.
        NzValue: z must be an instance of r   )r&   rU   rc   loadsri   r   r\   rT   )r/   rA   rR   r"   r"   r#   r      s    


zModelField.to_python)T)r5   r6   r7   r8   r>   ri   typingTyper	   rF   rE   rU   rT   rX   rZ   r\   r]   r`   ra   rf   rh   rB   rk   r   r:   r"   r"   )r1   r#   rC   e   s&   			rC   c                   sN   e Zd Zd	eje ejej ed fddZ	 fddZ
 fddZ  ZS )
FormedFieldN)rD   model_form_classmodel_form_kwargsc                s0   t  j|f|| || _|d kr&i }|| _d S )N)r-   rF   rp   rq   )r/   rD   rp   rq   rG   rH   )r1   r"   r#   rF     s
    zFormedField.__init__c                sB   t  j \}}}}| jd k	r&| j|d< | jr6| j|d< ||||fS )Nrp   rq   )r-   rf   rp   rq   )r/   r0   rg   rG   rH   )r1   r"   r#   rf     s    


zFormedField.deconstructc                s0   t | j| j| j| jd}|j| t jf |S )N)
form_classrD   rp   model_form_kwr0   )EmbeddedFormFieldrD   rp   rq   rL   updater-   	formfield)r/   rH   defaults)r1   r"   r#   rv      s    

zFormedField.formfield)NN)r5   r6   r7   rm   rn   r	   r   	ModelFormr>   rF   rf   rv   r:   r"   r"   )r1   r#   ro   
  s    &	ro   c                   s   e Zd ZdZdZeZ fddZee	j
eef d fddZee	j
eef d fdd	Zd
d Zdd Zd fdd	Z  ZS )
ArrayFielda]  
    Implements an array of objects inside the document.

    The allowed object type is defined on model declaration. The
    declared instance will accept a python list of instances of the
    given model as its contents.

    The model of the container must be declared as abstract, thus should
    not be treated as a collection of its own.
    Fc                s(   g }x|D ]}|j t j| q
W |S )N)appendr-   r\   )r/   rA   Z
post_value_dict)r1   r"   r#   r\   ;  s    
z ArrayField._value_thru_container)rN   rA   c                sR   t |trt j||f| S g }x*|D ]"}t j||f| }|j| q(W |S )N)r&   r>   r-   rT   rz   )r/   rN   rA   rQ   rR   pre_dict	post_dict)r1   r"   r#   rT   A  s    

zArrayField._value_thru_fieldsc                s4   g }x*|D ]"}t  j||f| }|j| q
W |S )N)r-   rX   rz   )r/   rN   rA   rQ   rR   r|   r}   )r1   r"   r#   rX   R  s    
z"ArrayField._save_value_thru_fieldsc             C   sH   | j |}g }x.|D ]&}| jf |}| jd|}|j| qW tj|S )Nr`   )ra   rD   rZ   rz   rc   rd   )r/   rY   rA   rR   r{   re   r}   r"   r"   r#   r`   ^  s    

zArrayField.value_to_stringc             C   sD   t || j}g }x.|D ]&}| jf |}| jd|}|j| qW |S )Nra   )r+   rL   rD   rZ   rz   )r/   rY   rA   rR   r{   re   r}   r"   r"   r#   ra   g  s    
zArrayField.value_from_objectTc                s6   t t| j|| x|D ]}t  j||dd qW d S )NF)r_   )r-   rC   r]   )r/   rA   r^   r_   r{   )r1   r"   r#   r]   p  s    
zArrayField.validate)T)r5   r6   r7   r8   r<   r?   ri   r\   rU   rm   Unionr>   rT   rX   r`   ra   r]   r:   r"   r"   )r1   r#   ry   -  s   

		ry   c             C   s@   | s<t tjtjd}|r0|r0tj|j|d|d< t|f|} | S )N)formfields)requestZformfield_callback)r>   r   rx   Z
ALL_FIELDS	functoolspartialZformfield_for_dbfieldr   )rp   rD   adminr   Zform_kwargsr"   r"   r#   _get_model_form_classv  s    
r   c                   s   e Zd Z fddZ  ZS )NestedFormSetc                sH   x0|j j D ]"\}}t|trd|j|f |_qW tt| j|| d S )Nz%s-%s)	r   itemsr&   ArrayFormFieldprefixr0   r-   r   
add_fields)r/   r   indexr0   r!   )r1   r"   r#   r     s    
zNestedFormSet.add_fields)r5   r6   r7   r   r:   r"   r"   )r1   r#   r     s   r   c                   s6   e Zd Zd
 fdd	Zdd Zdd Zdd	 Z  ZS )r   Nc                sv   || _ || _t||||| _|| _|| _|| _|s>t| jj}ddi}
t	j
| jtdd| _t j||
|d|	 d S )N
incompletezEnter all required fields.T)ZformsetZ
can_delete)error_messageswidget)r0   rD   r   rp   mdl_form_kw_lr   r   ArrayFormWidgetr5   r   Zformset_factoryr   ArrayFormSetr-   rF   )r/   r0   rp   rD   r   r   r   r   rG   rH   r   )r1   r"   r#   rF     s    zArrayFormField.__init__c             C   s|   |sg S | j || jd}|j rfg }x<|jD ]2}|jddr>q,|jd |j| jjj	f | q,W |S t
|j|j  d S )N)r   DELETET)r   r0   Zis_validZcleaned_datagetpoprz   rp   r   r   r   rV   Znon_form_errors)r/   rA   form_setretZitmr"   r"   r#   clean  s    
zArrayFormField.cleanc             C   sR   g }x2|pg D ]&}|j tj|| jjj| jjjd qW | j||| jd}|j	 S )N)r   exclude)initialr   )
rz   r   model_to_dictrp   r   r   r   r   r0   has_changed)r/   r   dataZform_set_initialinitr   r"   r"   r#   r     s    zArrayFormField.has_changedc             C   s   t || |S )N)ArrayFormBoundField)r/   r   r    r"   r"   r#   get_bound_field  s    zArrayFormField.get_bound_field)NNN)r5   r6   r7   rF   r   r   r   r:   r"   r"   )r1   r#   r     s   r   c                   s<   e Zd Z fddZdd Zdd Zdd Zd	d
 Z  ZS )r   c                s   t  j||| |jr| jnd }g }| jd k	rjx:| jD ]0}t|tr6|jtj	||j
jj|j
jjd q6W |j||| jd| _d S )N)r   r   )r   r   )r-   rF   Zis_boundr   r   r&   r	   rz   r   r   rp   r   r   r   r   Z	html_namer   )r/   r   r!   r0   r   r   Zini)r1   r"   r#   rF     s    

zArrayFormBoundField.__init__c             C   s   t |ttfst| j| S )N)r&   intslicerb   r   )r/   idxr"   r"   r#   __getitem__  s    zArrayFormBoundField.__getitem__c             c   s   x| j D ]
}|V  qW d S )N)r   )r/   r   r"   r"   r#   __iter__  s    zArrayFormBoundField.__iter__c             C   s6   t dddd | jD }td| j|}td|| jjS )N
z<tbody>{}</tbody>c             s   s   | ]}|j  fV  qd S )N)as_table).0r   r"   r"   r#   	<genexpr>  s   z.ArrayFormBoundField.__str__.<locals>.<genexpr>z1
<table class="{}-array-model-field">
{}
</table>z{}
{})r   r   r   r0   Zmanagement_form)r/   tabler"   r"   r#   __str__  s    zArrayFormBoundField.__str__c             C   s
   t | jS )N)lenr   )r/   r"   r"   r#   __len__  s    zArrayFormBoundField.__len__)	r5   r6   r7   rF   r   r   r   r   r:   r"   r"   )r1   r#   r     s
   r   c                   s@   e Zd Zd fdd	ZdddZdd Zdd	 Zd
d Z  ZS )r   Nc                s   || _ t j| d S )N)first_field_idr-   rF   )r/   r   attrs)r1   r"   r#   rF     s    zArrayFormWidget.__init__c             C   s   dst d S )NF)AssertionError)r/   r0   rA   r   Zrendererr"   r"   r#   render  s    zArrayFormWidget.renderc             C   s   dj || jS )Nz{}-0-{})formatr   )r/   Zid_r"   r"   r#   id_for_label  s    zArrayFormWidget.id_for_labelc                s    fdd D }|S )Nc                s    i | ]}|j r | |qS r"   )r*   )r   key)r   r0   r"   r#   
<dictcomp>   s    z7ArrayFormWidget.value_from_datadict.<locals>.<dictcomp>r"   )r/   r   filesr0   r   r"   )r   r0   r#   value_from_datadict  s    z#ArrayFormWidget.value_from_datadictc             C   s    x|D ]}|j |rdS qW dS )NFT)r*   )r/   r   r   r0   r   r"   r"   r#   value_omitted_from_data  s    

z'ArrayFormWidget.value_omitted_from_data)N)NN)	r5   r6   r7   rF   r   r   r   r   r:   r"   r"   )r1   r#   r     s
   
r   c               @   s   e Zd ZdS )EmbeddedFieldN)r5   r6   r7   r"   r"   r"   r#   r   
  s   r   c                   s6   e Zd Zd
 fdd	Zdd Zdd Zdd	 Z  ZS )rt   Nc                s0  g }	g }
g }|j  }y|d d | |d< W n tk
rH   ||d< Y nX |jdd }|rb||d< t||||| _|| _|| _|| _ddi}| jf || _xj| jj	j
 D ]Z\}}t|tjtjfrqnt|trd| jj|f |_|	j| |
j| |j|j qW t|
|}t j|||	|dd| d S )	Nr   -r   r   zEnter all required fields.z%s-%sF)r   r   r   Zrequire_all_fields)copyrP   r   r   rp   rq   r   r   
model_formr   r   r&   r   ZModelChoiceFieldModelMultipleChoiceFieldr   r   r0   rz   r   EmbeddedFormWidgetr-   rF   )r/   r0   rp   rs   rD   r   r   rG   rH   Zform_fieldsZmdl_form_field_nameswidgetsrq   r   r   r    r!   r   )r1   r"   r#   rF     s:    



zEmbeddedFormField.__init__c             C   s&   t t| jjj |}| jjjf |S )N)r>   zipr   r   keysr   r   )r/   Zclean_data_valsZmodel_fieldr"   r"   r#   compress7  s    zEmbeddedFormField.compressc             C   s(   |j rdj|j | jj | j_ t|| |S )Nz{}-{})r   r   r   EmbeddedFormBoundField)r/   r   r    r"   r"   r#   r   ;  s    z!EmbeddedFormField.get_bound_fieldc             C   s   | j r
|S | j|S )N)disabledr   )r/   r   r   r"   r"   r#   
bound_data@  s    zEmbeddedFormField.bound_data)NN)r5   r6   r7   rF   r   r   r   r:   r"   r"   )r1   r#   rt     s   'rt   c               @   s   e Zd Zdd ZdS )r   c             C   s6   | j  }| jjf d|i| jj}td|j  dS )Ninstancez<table>
z	
</table>)rA   r!   rp   rq   r   r   )r/   r   r   r"   r"   r#   r   M  s    zEmbeddedFormBoundField.__str__N)r5   r6   r7   r   r"   r"   r"   r#   r   F  s   r   c                   s4   e Zd Z fddZdd Zdd Zdd Z  ZS )	r   c                s   || _ t j|| d S )N)field_namesr-   rF   )r/   r   rG   rH   )r1   r"   r#   rF   U  s    zEmbeddedFormWidget.__init__c                sF    d krg S t  tr S t  tr8 fdd| jD S tjdd S )Nc                s   g | ]}t  |qS r"   )r+   )r   f_n)rA   r"   r#   
<listcomp>_  s    z1EmbeddedFormWidget.decompress.<locals>.<listcomp>zExpected model-form)r&   r?   r	   r   r   r   )r/   rA   r"   )rA   r#   
decompressY  s    

zEmbeddedFormWidget.decompressc             C   sF   g }x<t | jD ].\}}dj|| j| }|j|j||| qW |S )Nz{}-{})	enumerater   r   r   rz   r   )r/   r   r   r0   r   iZwidr   r"   r"   r#   r   c  s    z&EmbeddedFormWidget.value_from_datadictc                s"   t  fddtjD S )Nc             3   s.   | ]&\}}|j  d jj| V  qdS )z{}-{}N)r   r   r   )r   r   r   )r   r   r0   r/   r"   r#   r   n  s   z=EmbeddedFormWidget.value_omitted_from_data.<locals>.<genexpr>)allr   r   )r/   r   r   r0   r"   )r   r   r0   r/   r#   r   l  s    z*EmbeddedFormWidget.value_omitted_from_data)r5   r6   r7   rF   r   r   r   r:   r"   r"   )r1   r#   r   T  s   
	r   c               @   sB   e Zd ZedZdZdddZdd Zdd Zd	d
 Z	dd Z
dS )ObjectIdFieldMixinr   Fc             C   s
   | j |S )N)r   )r/   rA   rj   preparedr"   r"   r#   get_db_prep_valuey  s    z$ObjectIdFieldMixin.get_db_prep_valuec             C   s   t |trt|S |S )N)r&   rU   r   )r/   rA   r"   r"   r#   r   |  s    
zObjectIdFieldMixin.to_pythonc             C   s   dS )NObjectIdFieldr"   )r/   r"   r"   r#   get_internal_type  s    z$ObjectIdFieldMixin.get_internal_typec             C   s
   | j |S )N)Zdb_type)r/   rj   r"   r"   r#   rel_db_type  s    zObjectIdFieldMixin.rel_db_typec             C   s   |S )Nr"   )r/   rA   r"   r"   r#   rB     s    z!ObjectIdFieldMixin.get_prep_valueN)F)r5   r6   r7   _descriptionr<   r   r   r   r   rB   r"   r"   r"   r#   r   u  s   
r   c               @   s   e Zd ZdS )GenericObjectIdFieldN)r5   r6   r7   r"   r"   r"   r#   r     s   r   c               @   s   e Zd ZdS )_ObjectIdFieldN)r5   r6   r7   r"   r"   r"   r#   r     s   r   )	metaclassc               @   s   e Zd ZdS )r   N)r5   r6   r7   r"   r"   r"   r#   r     s   c                   s    e Zd ZdZ fddZ  ZS )r   z
    For every document inserted into a collection MongoDB internally creates an field.
    The field can be referenced from within the Model as _id.
    c                s&   ddd}|j | t j|| d S )NT)Zprimary_keyZauto_created)ru   r-   rF   )r/   rG   rH   Zid_field_args)r1   r"   r#   rF     s    
zObjectIdField.__init__)r5   r6   r7   r8   rF   r:   r"   r"   )r1   r#   r     s   r   c                   sZ   e Zd Zdd Z fddZ fddZde_ fdd	Zde_ fd
dZde_  Z	S )ArrayReferenceManagerMixinc             C   s2   |j | jd | jr |j| j}|jf | j}|S )zP
        Filter the queryset for the instance this manager is bound to.
        )r   )Z
_add_hintsr   _dbusingfiltercore_filters)r/   querysetr"   r"   r#   _apply_rel_filters  s
    z-ArrayReferenceManagerMixin._apply_rel_filtersc                s@   y| j j| jj  S  ttfk
r:   t j }| j|S X d S )N)	r   _prefetched_objects_cacher!   related_query_nameAttributeErrorrP   r-   get_querysetr   )r/   r   )r1   r"   r#   r     s
    
z'ArrayReferenceManagerMixin.get_querysetc                sF   t j| jj| jd}tt| j|jf |\}}|r>| j| ||fS )N)r   )	r   db_for_writer   r1   r-   r   
db_managerupdate_or_createadd)r/   rH   r3   rY   created)r1   r"   r#   r     s
    
z+ArrayReferenceManagerMixin.update_or_createTc                sF   t j| jj| jd}tt| j|jf |\}}|r>| j| ||fS )N)r   )	r   r   r   r1   r-   r   r   get_or_creater   )r/   rH   r3   rY   r   )r1   r"   r#   r     s
    
z(ArrayReferenceManagerMixin.get_or_createc                s:   t j| jj| jd}tt| j|jf |}| j| |S )N)r   )	r   r   r   r1   r-   r   r   creater   )r/   rH   r3   Znew_obj)r1   r"   r#   r     s    
z!ArrayReferenceManagerMixin.create)
r5   r6   r7   r   r   r   alters_datar   r   r:   r"   r"   )r1   r#   r     s   		r   c                s:   t | tr| }ntdt| fi }G  fdddt|}|S )N	baseclassc                   s   e Zd Z fddZfddZdZ fddZdd	 Zd
d Zde_	dd Z
de
_	dd Zde_	ddddZde_	dd Zde_	  ZS )zLcreate_reverse_array_reference_manager.<locals>.ReverseArrayReferenceManagerc                s6   t  j  || _j| _j| _jj}||i| _d S )N)	r-   rF   r   related_modelr   remote_fieldr!   r0   r   )r/   r   r0   )r1   relr"   r#   rF     s    
zUcreate_reverse_array_reference_manager.<locals>.ReverseArrayReferenceManager.__init__c               s$   t | j|}t|j }|| jdS )N)r   )r+   r   &create_reverse_array_reference_managerr1   r   )r/   managermanager_class)r   r"   r#   __call__  s    zUcreate_reverse_array_reference_manager.<locals>.ReverseArrayReferenceManager.__call__Tc                sp   t  j|}| jp"tj| j| jd}t| jj	}x:| j
jD ].}t| j|j}|d ks`|dkr:|r:|j S q:W |S )N)r    )r-   r   r   r   Zdb_for_readr   r   r   featuresZ!interprets_empty_strings_as_nullsr!   foreign_related_fieldsr+   rL   none)r/   r   r3   Zempty_strings_as_nullr!   val)r1   r"   r#   r     s    z_create_reverse_array_reference_manager.<locals>.ReverseArrayReferenceManager._apply_rel_filtersc             W   s*   t dd |D }| jjjjdt|iiS )Nc             s   s   | ]}|j V  qd S )N)pk)r   rY   r"   r"   r#   r     s    zlcreate_reverse_array_reference_manager.<locals>.ReverseArrayReferenceManager._make_filter.<locals>.<genexpr>z$in)setr   r   r   r0   r?   )r/   objsidsr"   r"   r#   _make_filter  s    
zYcreate_reverse_array_reference_manager.<locals>.ReverseArrayReferenceManager._make_filterc             W   st   | j | }| jjd \}}| j|d|j t| j|j ii x0|D ](}t||j }|jt| j|j  qDW d S )Nr   z	$addToSet)r   r!   related_fieldsmongo_updateget_attnamer+   r   r   )r/   r   Z_filterZlh_fieldrh_fieldrY   Zfk_fieldr"   r"   r#   r     s    

zPcreate_reverse_array_reference_manager.<locals>.ReverseArrayReferenceManager.addc             W   s   d S )Nr"   )r/   r   r"   r"   r#   remove  s    zScreate_reverse_array_reference_manager.<locals>.ReverseArrayReferenceManager.removec             S   s   d S )Nr"   )r/   r"   r"   r#   clear  s    zRcreate_reverse_array_reference_manager.<locals>.ReverseArrayReferenceManager.clearF)r  c            S   s   d S )Nr"   )r/   r   r  r"   r"   r#   r     s    zPcreate_reverse_array_reference_manager.<locals>.ReverseArrayReferenceManager.setc             [   s   d S )Nr"   )r/   rH   r"   r"   r#   r   $  s    zScreate_reverse_array_reference_manager.<locals>.ReverseArrayReferenceManager.create)r5   r6   r7   rF   r   do_not_call_in_templatesr   r   r   r   r  r  r   r   r:   r"   )r   )r1   r#   ReverseArrayReferenceManager  s   	r  )
issubclassr(   rK   r   )
superclassr   r   r  r"   )r   r#   r     s
    
Jr   c                s:   t | tr| }ntdt| fi }G  fdddt|}|S )Nr   c                   s   e Zd Z fddZfddZdZ fddZ fdd	Zd
d Zdd Z	de	_
dd Zde_
dd Zdd Zde_
ddddZde_
  ZS )zEcreate_forward_array_reference_manager.<locals>.ArrayReferenceManagerc                sh   t  j  || _j| _j| _t | _|| j_| jjd d j	}t
|| jj	pRg }| d|i| _d S )Nr      Z__in)r-   rF   r   r   r   r!   r(   instance_managerr   rL   r+   r   )r/   r   r0   r   )r1   r   r"   r#   rF   4  s    
zNcreate_forward_array_reference_manager.<locals>.ArrayReferenceManager.__init__c               s$   t | j|}t|j }|| jdS )N)r   )r+   r   &create_forward_array_reference_managerr1   r   )r/   r   r   )r   r"   r#   r   A  s    zNcreate_forward_array_reference_manager.<locals>.ArrayReferenceManager.__call__Tc                s(   t  j|}t| j| jjs$|j S |S )N)r-   r   r+   r   r!   rL   r   )r/   r   )r1   r"   r#   r   H  s    zXcreate_forward_array_reference_manager.<locals>.ArrayReferenceManager._apply_rel_filtersc                s@   y| j j| jj  S  ttfk
r:   t j }| j|S X d S )N)	r   r   r!   r   r   rP   r-   r   r   )r/   r   )r1   r"   r#   r   N  s
    
zRcreate_forward_array_reference_manager.<locals>.ArrayReferenceManager.get_querysetc             S   s   | j jjj| j jiS )N)r   r   r   r0   )r/   r"   r"   r#   r   U  s    zRcreate_forward_array_reference_manager.<locals>.ArrayReferenceManager._make_filterc             W   s   t | j| jj }|d kr4t }t| j| jj | t }| jjd }x |D ]}|jt ||j  qLW |j| t	j
| jj| jd}| jj|j| j d| jjdt|iii d S )Nr   )r   z	$addToSetz$each)r+   r   r!   r   r   setattrr   r   ru   r   r   r1   r  r   r   r   rL   r?   )r/   r   fksnew_fksr   rY   r3   r"   r"   r#   r   X  s    

zIcreate_forward_array_reference_manager.<locals>.ArrayReferenceManager.addc                s$   t  fdd|D } j| d S )Nc             3   s"   | ]}t | jjd  jV  qdS )r   N)r+   r!   r   rL   )r   rY   )r/   r"   r#   r   t  s   z_create_forward_array_reference_manager.<locals>.ArrayReferenceManager.remove.<locals>.<genexpr>)r   _remove)r/   r   to_delr"   )r/   r#   r  r  s    

zLcreate_forward_array_reference_manager.<locals>.ArrayReferenceManager.removec             S   sd   t | j| jj}|j| | jp2tj| jj| jd}| j	j
|j| j d| jjdt|iii d S )N)r   z$pullz$in)r+   r   r!   rL   difference_updater   r   r   r1   r  r   r   r   r?   )r/   r  r  r3   r"   r"   r#   r  {  s    
zMcreate_forward_array_reference_manager.<locals>.ArrayReferenceManager._removec             S   sP   t j| jj| jd}| jj|j| j d| jj	g ii t
| j| jj	t  d S )N)r   z$set)r   r   r   r1   r  r   r   r   r!   rL   r
  r   )r/   r3   r"   r"   r#   r    s    zKcreate_forward_array_reference_manager.<locals>.ArrayReferenceManager.clearF)r  c      	         s   t |}tj| jj| jd}tj|dd |rD| j  | j|  nt	| j| j
j}| j
jd  t fdd|D }|| }| j| t	| j| j
j}g }x(|D ] }t	| j |kr|j| qW | j| W d Q R X d S )N)r   F)r   Z	savepointr   c             3   s   | ]}t | j V  qd S )N)r+   r   )r   rY   )r   r"   r#   r     s    z\create_forward_array_reference_manager.<locals>.ArrayReferenceManager.set.<locals>.<genexpr>)tupler   r   r   r1   r   Zatomicr  r   r+   r!   rL   r   r   r  r   rz   )	r/   r   r  r3   r  r  r  Zto_addrY   r"   )r   r#   r     s"    

zIcreate_forward_array_reference_manager.<locals>.ArrayReferenceManager.set)r5   r6   r7   rF   r   r  r   r   r   r   r   r  r  r  r   r:   r"   )r   )r1   r#   ArrayReferenceManager2  s   r  )r  r(   rK   r   )r  r   r   r  r"   )r   r#   r	  ,  s
    
}r	  c               @   s*   e Zd Zdd Zedd ZdddZdS )	ArrayReferenceDescriptorc             C   s
   || _ d S )N)r!   )r/   Zfield_with_relr"   r"   r#   rF     s    z!ArrayReferenceDescriptor.__init__c             C   s   | j j}t|jj| j jS )N)r!   r   r	  _default_managerr1   r   )r/   r   r"   r"   r#   related_manager_cls  s    z,ArrayReferenceDescriptor.related_manager_clsNc             C   s   |dkr| S | j |S )a9  
        Get the related objects through the reverse relation.

        With the example above, when getting ``parent.children``:

        - ``self`` is the descriptor managing the ``children`` attribute
        - ``instance`` is the ``parent`` instance
        - ``cls`` is the ``Parent`` class (unused)
        N)r  )r/   r   clsr"   r"   r#   __get__  s    
z ArrayReferenceDescriptor.__get__)N)r5   r6   r7   rF   r   r  r  r"   r"   r"   r#   r    s   	r  c               @   s*   e Zd Zdd Zedd ZdddZdS )	ReverseArrayReferenceDescriptorc             C   s
   || _ d S )N)r   )r/   relatedr"   r"   r#   rF     s    z(ReverseArrayReferenceDescriptor.__init__c             C   s   | j j}t|jj| j S )N)r   r   r   r  r1   )r/   r   r"   r"   r#   r    s    z3ReverseArrayReferenceDescriptor.related_manager_clsNc             C   s   |dkr| S | j |S )a1  
        Get the related objects through the relation.

        With the example above, when getting ``parent.children``:

        - ``self`` is the descriptor managing the ``children`` attribute
        - ``instance`` is the ``parent`` instance
        - ``cls`` is the ``Parent`` class (unused)
        N)r  )r/   r   r  r"   r"   r#   r    s    
z'ReverseArrayReferenceDescriptor.__get__)N)r5   r6   r7   rF   r   r  r  r"   r"   r"   r#   r    s   	r  c                   s   e Zd ZdZdZdZdZdZeZ	e
Zd fdd	Zedd Zdd	d
Zdd ZdddZdd Zdd Zdd Zdd fdd
Z  ZS )ArrayReferenceFieldz
    When the entry gets saved, only a reference to the primary_key of the model is saved in the array.
    For all practical aspects, the ArrayReferenceField behaves like a Django ManyToManyField.
    FTNc	       
   
      s8   |p| j }t j|f|||||||d|	 d| _d S )N)	on_deleterelated_namer   limit_choices_toparent_linkto_fielddb_constraintF)
_on_deleter-   rF   r%   )
r/   Ztor  r  r   r  r  r  r  rH   )r1   r"   r#   rF     s    
zArrayReferenceField.__init__c             C   sB   x<| j j D ].\}}x$|D ]}t||jj|j|  qW qW d S )N)r   r   r+   r0   r   r  )	collectorr!   Zsub_objsr   r   Z	instancesrY   r"   r"   r#   r     s    
zArrayReferenceField._on_deletec             C   s
   | j |S )N)r   )r/   rA   Z
expressionrj   contextr"   r"   r#   rk     s    z!ArrayReferenceField.from_db_valuec             C   s   |d krt  S t |S )N)r   )r/   rA   r"   r"   r#   r     s    zArrayReferenceField.to_pythonc             C   s"   |d krg S t |trt|S |S )N)r&   r   r?   )r/   rA   rj   r   r"   r"   r#   r     s
    
z%ArrayReferenceField.get_db_prep_valuec             C   s   | j ||S )N)r   )r/   rA   rj   r"   r"   r#   rh   &  s    z$ArrayReferenceField.get_db_prep_savec             C   s   d S )Nr"   )r/   rA   r^   r"   r"   r#   r]   ,  s    zArrayReferenceField.validatec             C   s   t || jjt|dd d S )NT)r  )r+   r0   r   r?   )r/   r   r   r"   r"   r#   save_form_data0  s    z"ArrayReferenceField.save_form_data)r   c               s`   t j| jjjj|d|}|jdd k	rR|d }t|r@| }dd |D |d< t j	f |S )N)rr   r   r   c             S   s   g | ]
}|j qS r"   )r   )r   r   r"   r"   r#   r   ?  s    z1ArrayReferenceField.formfield.<locals>.<listcomp>)
r   r   r   r   r  r   r   callabler-   rv   )r/   r   rH   rw   r   )r1   r"   r#   rv   3  s    zArrayReferenceField.formfield)NNNNFNT)N)F)r5   r6   r7   r8   Zmany_to_manyZmany_to_oneZone_to_manyZ
one_to_oner  Zrelated_accessor_classr  Zforward_related_accessor_classrF   staticmethodr   rk   r   r   rh   r]   r#  rv   r:   r"   r"   )r1   r#   r    s$     

r  )Qr8   r   rc   rm   Zbsonr   Zdjangor   Zdjango.core.exceptionsr   Z	django.dbr   r2   r   r   Zdjango.db.modelsr   r	   r
   r   r   r   Zdjango.utilsr   Zdjango.db.models.fields.relatedr   Zdjango.formsr   Zdjango.utils.functionalr   Zdjango.utils.htmlr   r   Zdjango.utils.safestringr   Zdjango.utils.translationr   r   Zdjongo.exceptionsr   r   r   get_versionsplitZdjango_majorZdjango.db.models.fieldsr   r   r$   r'   r(   r;   r=   rC   ro   ry   r   ZformsetsZBaseFormSetr   r   Z
BoundFieldr   ZWidgetr   r   ZMultiValueFieldrt   r   ZMultiWidgetr   r   r   r   r   r   r   r	  r  r  r  r"   r"   r"   r#   <module>   sf    
 &#I:,8!
3S %