U
    8ÄT_‘H  ã                   @   sä   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
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
ZdZdZdZdZdZdZd ZdZG dd„ deƒZeG dd„ dƒƒZ e dddddddfdd„Z!dd„ Z"dS )é    )ÚValidationError)ÚForm)ÚBooleanFieldÚIntegerField)Ú	ErrorList)ÚHiddenInputÚNumberInput)Úcached_property)Ú	html_safe)Ú	mark_safe)ÚgettextÚngettext)ÚBaseFormSetÚformset_factoryÚ	all_validZTOTAL_FORMSZINITIAL_FORMSZMIN_NUM_FORMSZMAX_NUM_FORMSZORDERÚDELETEiè  c                       s    e Zd ZdZ‡ fdd„Z‡  ZS )ÚManagementFormz±
    Keep track of how many form instances are displayed on the page. If adding
    new forms via JavaScript, you should increment the count field of this form
    as well.
    c                    sV   t td�| jt< t td�| jt< t dtd�| jt< t dtd�| jt< tƒ j||Ž d S )N)ÚwidgetF)Úrequiredr   )	r   r   Zbase_fieldsÚTOTAL_FORM_COUNTÚINITIAL_FORM_COUNTÚMIN_NUM_FORM_COUNTÚMAX_NUM_FORM_COUNTÚsuperÚ__init__)ÚselfÚargsÚkwargs©Ú	__class__© ú9/tmp/pip-unpacked-wheel-dv63caxw/django/forms/formsets.pyr   "   s
    zManagementForm.__init__)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Ú__classcell__r    r    r   r!   r      s   r   c                   @   sl  e Zd ZdZeZdddddedfdd„Zdd„ Zdd	„ Z	d
d„ Z
dd„ Zdd„ Zedd„ ƒZdd„ Zdd„ Zedd„ ƒZdd„ Zdd„ Zedd„ ƒZedd„ ƒZed d!„ ƒZed"d#„ ƒZed$d%„ ƒZed&d'„ ƒZed(d)„ ƒZed*d+„ ƒZd,d-„ Zed.d/„ ƒZd0d1„ Z d2d3„ Z!d4d5„ Z"d6d7„ Z#d8d9„ Z$d:d;„ Z%d<d=„ Z&d>d?„ Z'd@dA„ Z(edBdC„ ƒZ)dDdE„ Z*dFdG„ Z+dHdI„ Z,dS )Jr   z;
    A collection of instances of the same Form class.
    Nzid_%sc                 C   s`   |d k	p|d k	| _ |p|  ¡ | _|| _|p,i | _|p6i | _|| _|pFi | _|| _d | _	d | _
d S ©N)Úis_boundÚget_default_prefixÚprefixÚauto_idÚdataÚfilesÚinitialÚform_kwargsÚerror_classÚ_errorsÚ_non_form_errors)r   r,   r-   r+   r*   r.   r0   r/   r    r    r!   r   4   s    


zBaseFormSet.__init__c                 C   s   |   ¡ S r'   ©Úas_table©r   r    r    r!   Ú__str__A   s    zBaseFormSet.__str__c                 C   s
   t | jƒS )z5Yield the forms in the order they should be rendered.)ÚiterÚformsr5   r    r    r!   Ú__iter__D   s    zBaseFormSet.__iter__c                 C   s
   | j | S )zAReturn the form at the given index, based on the rendering order.©r8   ©r   Úindexr    r    r!   Ú__getitem__H   s    zBaseFormSet.__getitem__c                 C   s
   t | jƒS r'   )Úlenr8   r5   r    r    r!   Ú__len__L   s    zBaseFormSet.__len__c                 C   s   dS )zt
        Return True since all formsets have a management form which is not
        included in the length.
        Tr    r5   r    r    r!   Ú__bool__O   s    zBaseFormSet.__bool__c                 C   sf   | j r4t| j| j| jd�}| ¡ sbttdƒdd�‚n.t| j| jt|  	¡ t
|  ¡ t| jt| jid�}|S )z4Return the ManagementForm instance for this FormSet.)r+   r*   z8ManagementForm data is missing or has been tampered withZmissing_management_form©Úcode)r+   r*   r.   )r(   r   r,   r+   r*   Úis_validr   Ú_r   Útotal_form_countr   Úinitial_form_countr   Úmin_numr   Úmax_num©r   Úformr    r    r!   Úmanagement_formV   s$    þ
    üzBaseFormSet.management_formc                 C   sx   | j rt| jjt | jƒS |  ¡ }t|| jƒ| j	 }|| j
  krJdkrTn n|}n || j
  krjdkrtn n| j
}|S )z1Return the total number of forms in this FormSet.r   )r(   ÚminrK   Úcleaned_datar   Úabsolute_maxrF   ÚmaxrG   ÚextrarH   )r   Úinitial_formsZtotal_formsr    r    r!   rE   i   s    zBaseFormSet.total_form_countc                 C   s*   | j r| jjt S | jr"t| jƒnd}|S )z=Return the number of forms that are required in this FormSet.r   )r(   rK   rM   r   r.   r>   )r   rQ   r    r    r!   rF   |   s    zBaseFormSet.initial_form_countc                    s   ‡ fdd„t ˆ  ¡ ƒD ƒS )z+Instantiate forms at first property access.c                    s    g | ]}ˆ j |fˆ  |¡Ž‘qS r    )Ú_construct_formÚget_form_kwargs©Ú.0Úir5   r    r!   Ú
<listcomp>‰   s   ÿz%BaseFormSet.forms.<locals>.<listcomp>)ÚrangerE   r5   r    r5   r!   r8   …   s    

þzBaseFormSet.formsc                 C   s
   | j  ¡ S )z®
        Return additional keyword arguments for each individual formset form.

        index will be None if the form being constructed is a new empty
        form.
        )r/   Úcopyr;   r    r    r!   rS   Ž   s    zBaseFormSet.get_form_kwargsc                 K   s¬   | j |  |¡| jddœ}| jr2| j|d< | j|d< | jrhd|krhz| j| |d< W n tk
rf   Y nX ||  ¡ kr†|| j	kr†d|d< | 
|¡ | jf |Ž}|  ||¡ |S )z;Instantiate and return the i-th form instance in a formset.F)r+   r*   r0   Úuse_required_attributer,   r-   r.   TÚempty_permitted)r+   Ú
add_prefixr0   r(   r,   r-   r.   Ú
IndexErrorrF   rG   ÚupdaterJ   Ú
add_fields)r   rV   r   ÚdefaultsrJ   r    r    r!   rR   —   s&    ù	


zBaseFormSet._construct_formc                 C   s   | j d|  ¡ … S )z7Return a list of all the initial forms in this formset.N©r8   rF   r5   r    r    r!   rQ   ³   s    zBaseFormSet.initial_formsc                 C   s   | j |  ¡ d… S )z5Return a list of all the extra forms in this formset.Nra   r5   r    r    r!   Úextra_forms¸   s    zBaseFormSet.extra_formsc                 C   s8   | j f | j|  d¡dddœ|  d ¡—Ž}|  |d ¡ |S )NZ
__prefix__TF)r+   r*   r[   rZ   )rJ   r+   r\   rS   r_   rI   r    r    r!   Ú
empty_form½   s    üûzBaseFormSet.empty_formc                 C   s(   |   ¡ std| jj ƒ‚dd„ | jD ƒS )zX
        Return a list of form.cleaned_data dicts for every form in self.forms.
        z+'%s' object has no attribute 'cleaned_data'c                 S   s   g | ]
}|j ‘qS r    )rM   ©rU   rJ   r    r    r!   rW   Ð   s     z,BaseFormSet.cleaned_data.<locals>.<listcomp>)rC   ÚAttributeErrorr   r"   r8   r5   r    r    r!   rM   É   s    zBaseFormSet.cleaned_datac                    s€   ˆ   ¡ rˆ jsg S tˆ dƒslg ˆ _tdˆ  ¡ ƒD ]:}ˆ j| }|ˆ  ¡ krT| ¡ sTq0ˆ  	|¡r0ˆ j 
|¡ q0‡ fdd„ˆ jD ƒS )z:Return a list of forms that have been marked for deletion.Ú_deleted_form_indexesr   c                    s   g | ]}ˆ j | ‘qS r    r:   rT   r5   r    r!   rW   â   s     z-BaseFormSet.deleted_forms.<locals>.<listcomp>)rC   Ú
can_deleteÚhasattrrf   rX   rE   r8   rF   Úhas_changedÚ_should_delete_formÚappend)r   rV   rJ   r    r5   r!   Údeleted_formsÒ   s    


zBaseFormSet.deleted_formsc                    s´   ˆ   ¡ rˆ jstdˆ jj ƒ‚tˆ dƒs g ˆ _tdˆ  ¡ ƒD ]L}ˆ j	| }|ˆ  
¡ kr`| ¡ s`q<ˆ jrrˆ  |¡rrq<ˆ j ||jt f¡ q<dd„ }ˆ jj|d� ‡ fdd„ˆ jD ƒS )	z�
        Return a list of form in the order specified by the incoming data.
        Raise an AttributeError if ordering is not allowed.
        z,'%s' object has no attribute 'ordered_forms'Ú	_orderingr   c                 S   s   | d d krdS d| d fS )Né   )rn   r   r   r    )Úkr    r    r!   Úcompare_ordering_key  s    z7BaseFormSet.ordered_forms.<locals>.compare_ordering_key)Úkeyc                    s   g | ]}ˆ j |d   ‘qS )r   r:   rT   r5   r    r!   rW     s     z-BaseFormSet.ordered_forms.<locals>.<listcomp>)rC   Ú	can_orderre   r   r"   rh   rm   rX   rE   r8   rF   ri   rg   rj   rk   rM   ÚORDERING_FIELD_NAMEÚsort)r   rV   rJ   rp   r    r5   r!   Úordered_formsä   s    

zBaseFormSet.ordered_formsc                 C   s   dS )NrJ   r    ©Úclsr    r    r!   r)   
  s    zBaseFormSet.get_default_prefixc                 C   s   | j S r'   )Úordering_widgetrv   r    r    r!   Úget_ordering_widget  s    zBaseFormSet.get_ordering_widgetc                 C   s   | j dkr|  ¡  | j S )z¹
        Return an ErrorList of errors that aren't associated with a particular
        form -- i.e., from formset.clean(). Return an empty ErrorList if there
        are none.
        N)r2   Ú
full_cleanr5   r    r    r!   Únon_form_errors  s    
zBaseFormSet.non_form_errorsc                 C   s   | j dkr|  ¡  | j S )z:Return a list of form.errors for every form in self.forms.N)r1   rz   r5   r    r    r!   Úerrors  s    
zBaseFormSet.errorsc                 C   s    t |  ¡ ƒtdd„ | jD ƒƒ S )z<Return the number of errors across all forms in the formset.c                 s   s   | ]}t |ƒV  qd S r'   )r>   )rU   Úform_errorsr    r    r!   Ú	<genexpr>&  s     z0BaseFormSet.total_error_count.<locals>.<genexpr>)r>   r{   Úsumr|   r5   r    r    r!   Útotal_error_count#  s    
ÿzBaseFormSet.total_error_countc                 C   s   |j  td¡S )z7Return whether or not the form was marked for deletion.F)rM   ÚgetÚDELETION_FIELD_NAMErI   r    r    r!   rj   (  s    zBaseFormSet._should_delete_formc                 C   s^   | j s
dS d}| j td|  ¡ ƒD ],}| j| }| jrB|  |¡rBq"|| ¡ M }q"|o\|  ¡  S )z1Return True if every form in self.forms is valid.FTr   )	r(   r|   rX   rE   r8   rg   rj   rC   r{   )r   Zforms_validrV   rJ   r    r    r!   rC   ,  s    
zBaseFormSet.is_validc              
   C   sN  g | _ |  ¡ | _d}| jsdS td|  ¡ ƒD ]N}| j| }| ¡ sV||  ¡ krV|d7 }|j	}| j
rn|  |¡rnq,| j  |¡ q,zš| jrœ|  ¡ t| jƒ | jks®| jjt | jkrÊttdd| jƒ| j dd�‚| j�r|  ¡ t| jƒ | | jk �rttdd| jƒ| j dd�‚|  ¡  W n2 tk
�rH } z|  |j¡| _W 5 d}~X Y nX dS )	ze
        Clean all of self.data and populate self._errors and
        self._non_form_errors.
        r   Nrn   z Please submit %d or fewer forms.Ztoo_many_formsrA   zPlease submit %d or more forms.Ztoo_few_forms)r1   r0   r2   r(   rX   rE   r8   ri   rF   r|   rg   rj   rk   Úvalidate_maxr>   rl   rH   rK   rM   r   rN   r   r   Úvalidate_minrG   ÚcleanZ
error_list)r   Zempty_forms_countrV   rJ   r}   Úer    r    r!   rz   >  sV    

ÿþ þþýÿ þþýzBaseFormSet.full_cleanc                 C   s   dS )a  
        Hook for doing any extra formset-wide cleaning after Form.clean() has
        been called on every form. Any ValidationError raised by this method
        will not be associated with a particular form; it will be accessible
        via formset.non_form_errors()
        Nr    r5   r    r    r!   r…   h  s    zBaseFormSet.cleanc                 C   s   t dd„ | D ƒƒS )z5Return True if data in any form differs from initial.c                 s   s   | ]}|  ¡ V  qd S r'   )ri   rd   r    r    r!   r~   s  s     z*BaseFormSet.has_changed.<locals>.<genexpr>)Úanyr5   r    r    r!   ri   q  s    zBaseFormSet.has_changedc                 C   sz   | j rZ|dk	r>||  ¡ k r>ttdƒ|d d|  ¡ d�|jt< nttdƒd|  ¡ d�|jt< | jrvttdƒdd�|jt	< dS )	z8A hook for adding extra fields on to each form instance.NZOrderrn   F)Úlabelr.   r   r   )rˆ   r   r   ZDelete)rˆ   r   )
rr   rF   r   rD   ry   Úfieldsrs   rg   r   r‚   )r   rJ   r<   r    r    r!   r_   u  s    üýzBaseFormSet.add_fieldsc                 C   s   d| j |f S )Nz%s-%s)r*   r;   r    r    r!   r\   ‰  s    zBaseFormSet.add_prefixc                 C   s"   | j r| j d  ¡ S | j ¡ S dS )zv
        Return True if the formset needs to be multipart, i.e. it
        has FileInput, or False otherwise.
        r   N)r8   Úis_multipartrc   r5   r    r    r!   rŠ   Œ  s    zBaseFormSet.is_multipartc                 C   s   | j r| j d jS | jjS d S )Nr   )r8   Úmediarc   r5   r    r    r!   r‹   –  s    zBaseFormSet.mediac                 C   s*   d  dd„ | D ƒ¡}tt| jƒd | ƒS )zLReturn this formset rendered as HTML <tr>s -- excluding the <table></table>.ú c                 s   s   | ]}|  ¡ V  qd S r'   r3   rd   r    r    r!   r~   ¤  s     z'BaseFormSet.as_table.<locals>.<genexpr>Ú
©Újoinr   ÚstrrK   ©r   r8   r    r    r!   r4   Ÿ  s    zBaseFormSet.as_tablec                 C   s*   d  dd„ | D ƒ¡}tt| jƒd | ƒS )z*Return this formset rendered as HTML <p>s.rŒ   c                 s   s   | ]}|  ¡ V  qd S r'   )Úas_prd   r    r    r!   r~   ©  s     z#BaseFormSet.as_p.<locals>.<genexpr>r�   rŽ   r‘   r    r    r!   r’   §  s    zBaseFormSet.as_pc                 C   s*   d  dd„ | D ƒ¡}tt| jƒd | ƒS )z+Return this formset rendered as HTML <li>s.rŒ   c                 s   s   | ]}|  ¡ V  qd S r'   )Úas_ulrd   r    r    r!   r~   ®  s     z$BaseFormSet.as_ul.<locals>.<genexpr>r�   rŽ   r‘   r    r    r!   r“   ¬  s    zBaseFormSet.as_ul)-r"   r#   r$   r%   r   rx   r   r   r6   r9   r=   r?   r@   r	   rK   rE   rF   r8   rS   rR   ÚpropertyrQ   rb   rc   rM   rl   ru   Úclassmethodr)   ry   r{   r|   r€   rj   rC   rz   r…   ri   r_   r\   rŠ   r‹   r4   r’   r“   r    r    r    r!   r   -   sj     ÿ

	
	





%



*	

r   rn   FNc	              
   C   sL   |dkrt }|dkrt}|t }	| ||||||	||dœ	}
t| jd |f|
ƒS )z*Return a FormSet for the given form class.N)	rJ   rP   rr   rg   rG   rH   rN   r„   rƒ   ZFormSet)ÚDEFAULT_MIN_NUMÚDEFAULT_MAX_NUMÚtyper"   )rJ   ÚformsetrP   rr   rg   rH   rƒ   rG   r„   rN   Úattrsr    r    r!   r   ²  s     ÷r   c                 C   s   d}| D ]}||  ¡ M }q|S )z8Validate every formset and return True if all are valid.T)rC   )ZformsetsZvalidr™   r    r    r!   r   Ì  s    r   )#Zdjango.core.exceptionsr   Zdjango.formsr   Zdjango.forms.fieldsr   r   Zdjango.forms.utilsr   Zdjango.forms.widgetsr   r   Zdjango.utils.functionalr	   Zdjango.utils.htmlr
   Zdjango.utils.safestringr   Zdjango.utils.translationr   rD   r   Ú__all__r   r   r   r   rs   r‚   r–   r—   r   r   r   r   r    r    r    r!   Ú<module>   s>         þ
