
^Q\2                 @   s  d  d l  m Z m 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 d  d l m Z d  d	 l m Z d  d
 l m Z e j d d    Z Gd d   d e  Z Gd d   d e e  Z Gd d   d e e
  Z d S)    )absolute_importunicode_literalsN)models)ValidationError)BaseGenericInlineFormSet)ContentType)BaseInlineFormSet)
force_text)six)xrangec             c   sQ   d  } t  |  d d   d k r0 d } d |  _ n  d  V| d  k	 rM | |  _ n  d  S)N_mutableFT)getattrr   )ZqdZorig_mutable r   H/var/www/dbchiro/venv/build/django-nested-admin/nested_admin/formsets.pymutable_querydict   s    r   c                   s   e  Z d  Z d Z   f d d   Z d d d  Z d d   Z d	 d
 d  Z   f d d   Z d	 d d d  Z	 d	 d d d  Z
   S)NestedInlineFormSetMixinFc                sH   i  } d |  j  k r" d | d <n  | j |  t t |   j | |  S)Nz-empty-TZempty_permitted)prefixupdatesuperr   _construct_form)selfikwargsdefaults)	__class__r   r   r      s
    z(NestedInlineFormSetMixin._construct_formTc       
         sP  g    _  g    _ g    _ | sH g    _   f d d   } |   _ n    j   } g  } xH t   j  D]7 \ } } | | _ t	 | | k   | _
 | j |  qj W  j |  } g  } g  } xs | D]k }   j | | |  }	 |	 d k	 r
| j |	 _ | |	 g 7} n	 | j }	   j |  s | j |	  q q W| j d d d    | S)z
        Saves model instances for every form, adding and changing instances
        as necessary, and returns the list of instances.
        c                 s"   x   j  D] }  |  j   q
 Wd  S)N)saved_formssave_m2m)form)r   r   r   r   2   s    z/NestedInlineFormSetMixin.save.<locals>.save_m2mNkeyc             S   s   |  j  S)N)_list_position)r   r   r   r   <lambda>^   s    z/NestedInlineFormSetMixin.save.<locals>.<lambda>)changed_objectsdeleted_objectsnew_objectsr   r   initial_form_count	enumerateformsr   bool_is_initialappendprocess_forms_pre_saveget_saved_instance_for_forminstance_should_delete_formsort)
r   commitr   r$   r&   r   r   form_instancessaved_instancesr,   r   )r   r   save&   s4    						zNestedInlineFormSetMixin.savec                s;  t  |  d d      f d d   }   d k	 r7| j d |  d } x | D] } |  j |  rh qM n  | j j | j     } d | | k r&| j r | j r qM n  t | j	   |  t
 | j  $ t j |  | j | j    <Wd QXt j d k r| j j d
 d  q&d | _ n  | d 7} qM Wn  | S)aS  
        Sort by the sortable_field_name of the formset, if it has been set,
        and re-index the form positions (to account for gaps caused by blank
        or deleted forms)

        Allows customizable sorting and modification of self.forms before
        they're iterated through in save().

        Returns list of forms.
        Zsortable_field_nameNc                s#   t  |  d i d   6 j   d  S)Ncleaned_datar   )r   get)r   )
sort_fieldr   r   get_positionn   s    zENestedInlineFormSetMixin.process_forms_pre_save.<locals>.get_positionr   r   z%s   	   changed_data)r7   r8   )r   r.   r-   datar4   
add_prefixr9   r(   setattrr,   r   r
   	text_typedjangoVERSION__dict__pop_changed_data)r   r&   r6   r   r   Zoriginal_positionr   )r5   r   r*   a   s(    %z/NestedInlineFormSetMixin.process_forms_pre_saveNc       
      C   sp  d  } | j  r3 | j  j j r3 | j  j j j } n  d  } | j rg t | d  rg | j j |  } n  t | t	 j
  r | j } n  | d  k	 r| j  j j j   } t | j  | d   } | | k ry t | j  | |  Wq	t k
 rt | j  | |  Yq	Xqn  | j r-|  j | g |  } n |  j | g |  } t |  rh| d }	 | j |	 _ |	 Sd  Sd  S)Nr3   r   )r,   _metapknameerrorshasattrr3   r4   
isinstancer   ZModelget_attnamer   r<   
ValueErrorr(   save_existing_objectssave_new_objectslenr   )
r   r   r/   r0   pk_nameZpk_valZ
pk_attnameZorig_valZ	instancesr,   r   r   r   r+      s0    	
z4NestedInlineFormSetMixin.get_saved_instance_for_formc                s     j  s t t    j   St   d  s   f d d   t d   j    D }   f d d   | D }   j j j   } | j	 d |  } | j
 s | j   j j j j  } n  |   _ n    j S)z5
        TODO: document this extended method
        Z
__querysetc                s5   g  |  ]+ } d    j  |    j j j j f  q S)z%s-%s)r;   modelrC   rD   rE   ).0r   )r   r   r   
<listcomp>   s   	z9NestedInlineFormSetMixin.get_queryset.<locals>.<listcomp>r   c                s4   g  |  ]* }   j  j |  r   j  j |   q Sr   )r:   r4   )rP   Zpk_key)r   r   r   rQ      s   	 Zpk__in)r:   r   r   get_querysetrG   r   r$   rO   Z_default_managerfilterorderedZorder_byrC   rD   rE   Z#_NestedInlineFormSetMixin__queryset)r   Zpk_keysZpk_valsqs)r   )r   r   rR      s    		z%NestedInlineFormSetMixin.get_querysetc             C   s  | s
 g  Sg  } |  j  } x| D]} |  j j } t | d  sr | j | j j | j | j | j	 |   } n | j
 |  } |  j |  r | } n y | j | j |  } Wn t k
 rWt | j   d | j | j	 |  <Wd QX| j   s4t j d k r!| j d j |  q4| j j |  n  | j |  j | g |   w  Yn Xt | d |  } d }	 |	 d k r| j r| r| j j }
 y |
 j j d |  }	 Wq|
 j k
 r| rt | j j  t |  k r| j }	 n  YqXn  |	 d k r|  j |  }	 n  | | k rs|  j  j |	  t |  d  rZ|  j! |	 d	 | q  | r  |	 j"   q  q  n  t# j j$ |  j j  j } } |  j j } } | j j r;|  j% j j d | j j  } t |  d
 t |  d d   } | rt | | j&    } n  t |  d d  } | r;t | | j&    } q;n  | j   s_| | k s_| | k r  |  j' j |	 | j( f  | j |  j) | |	 d	 |  | s|  j* j |  qq  q  W| S)z
        Identical to parent class, except ``self.initial_forms`` is replaced
        with ``initial_forms``, passed as parameter.
        
_raw_value Nr7   r8   r9   rD   delete_existingr/   Zfkct_fk_fieldct_field)r7   r8   )+Zdeleted_formsZ	_pk_fieldrE   rG   fieldsZwidgetZvalue_from_datadictr:   filesr;   rV   r-   cleanr   r   has_changedr>   r?   r@   r)   rB   extendrL   r   r,   r   objectsr4   ZDoesNotExistr	   rD   Z_existing_objectr"   rX   deleter   get_for_modelrO   rI   r!   r9   save_existingr   )r   Zinitial_formsr/   r1   Zforms_to_deleter   rN   Zraw_pk_valueZpk_valueobjZ	model_clsZ
old_ct_valZct_valZ
old_fk_valZfk_valZoriginal_instanceZfk_fieldrZ   r   r   r   rK      sr    	!	$$z.NestedInlineFormSetMixin.save_existing_objectsc             C   s   g  } | d k r | Sxs | D]k } | j    s5 q n  |  j rS |  j |  rS q n  | j |  j | d |  | s |  j j |  q q W|  j j |  | S)z
        Identical to parent class, except ``self.extra_forms`` is replaced
        with ``extra_forms``, passed as parameter, and self.new_objects is
        replaced with ``new_objects``.
        Nr/   )r^   Z
can_deleter-   r)   save_newr   r#   r_   )r   Zextra_formsr/   r#   r   r   r   r   rL     s    z)NestedInlineFormSetMixin.save_new_objects)__name__
__module____qualname__Z	is_nestedr   r2   r*   r+   rR   rK   rL   r   r   )r   r   r      s   ;0Vr   c               @   s   e  Z d  Z d Z d S)NestedInlineFormSetzK
    The nested InlineFormSet for the common case (ForeignKey inlines)
    N)rf   rg   rh   __doc__r   r   r   r   ri   8  s   ri   c               @   s%   e  Z d  Z d Z d d d  Z d S)NestedBaseGenericInlineFormSetzP
    The nested InlineFormSet for inlines of generic content-type relations
    Tc             C   s`   t  | j |  j j   t j j |  j  j  t  | j |  j j   |  j j  | j	 d |  S)z@Saves and returns an existing model instance for the given form.r/   )
r<   r,   rZ   rI   r   r`   rb   rD   rY   r2   )r   r   r,   r/   r   r   r   rc   D  s
    z,NestedBaseGenericInlineFormSet.save_existingN)rf   rg   rh   rj   rc   r   r   r   r   rk   ?  s   rk   )
__future__r   r   
contextlibr>   Z	django.dbr   Zdjango.core.exceptionsr   Z!django.contrib.contenttypes.formsr   Z"django.contrib.contenttypes.modelsr   Zdjango.forms.modelsr   Zdjango.utils.encodingr	   Zdjango.utilsr
   Zdjango.utils.six.movesr   contextmanagerr   objectr   ri   rk   r   r   r   r   <module>   s    