U
    Ha-                     @   s   d Z ddlmZ ddlmZ ddlmZ e ZG dd de	Z
G dd deZG d	d
 d
eZG dd deZG dd dZG dd dZG dd dZG dd dZdd Zdd Zdd ZdS )z;
Module for abstract serializer/unserializer base classes.
    )StringIO)ObjectDoesNotExist)modelsc                   @   s   e Zd ZdZdS )SerializerDoesNotExistz'The requested serializer was not found.N__name__
__module____qualname____doc__ r   r   @/tmp/pip-unpacked-wheel-3jxiddxt/django/core/serializers/base.pyr      s   r   c                   @   s   e Zd ZdZdS )SerializationErrorz,Something bad happened during serialization.Nr   r   r   r   r   r      s   r   c                   @   s   e Zd ZdZedd ZdS )DeserializationErrorz.Something bad happened during deserialization.c                 C   s   | d||||f S )zs
        Factory method for creating a deserialization error which has a more
        explanatory message.
        z#%s: (%s:pk=%s) field_value was '%s'r   )clsoriginal_excmodelZfkfield_valuer   r   r   WithData   s    zDeserializationError.WithDataN)r   r   r	   r
   classmethodr   r   r   r   r   r      s   r   c                   @   s   e Zd ZdZdd ZdS )M2MDeserializationErrorzCSomething bad happened during deserialization of a ManyToManyField.c                 C   s   || _ || _d S N)r   pk)selfr   r   r   r   r   __init__$   s    z M2MDeserializationError.__init__N)r   r   r	   r
   r   r   r   r   r   r   "   s   r   c                   @   s    e Zd ZdZdd Zdd ZdS )ProgressBarK   c                 C   s   || _ || _d| _d S )Nr   )outputtotal_count	prev_done)r   r   r   r   r   r   r   ,   s    zProgressBar.__init__c                 C   s   | j s
d S |d | j }|| j d }| j|kr4d S || _| jdkrHdnd}| j |d d|  d| j|   d  || jkr| j d	 | j   d S )
Nd       [. ]
)r   r   progress_widthr   writeflush)r   countpercdoneZcrr   r   r   update1   s    
*
zProgressBar.updateN)r   r   r	   r(   r   r.   r   r   r   r   r   )   s   r   c                   @   st   e Zd ZdZdZeZeZdddddddddZ	dd	 Z
d
d Zdd Zdd Zdd Zdd Zdd Zdd ZdS )
Serializerz)
    Abstract serializer base class.
    FNr   )streamfieldsuse_natural_foreign_keysuse_natural_primary_keysprogress_outputobject_countc                K   s  || _ |dk	r|n|  | _|| _|| _|| _| ||}	|   d| _t	|ddD ]\}
}| 
| |jj}| jr|jj}|jr|jjr|nd}nd}|jjD ]l}|js||kr|jdkr| jdks|j| jkr| || q| jdks|jdd | jkr| || q|jjD ]4}|jr| jdks>|j| jkr| || q| | |	|
 | jold| _qT|   |  S )z'
        Serialize a queryset.
        NTr    )startF)optionsstream_classr0   Zselected_fieldsr2   r3   progress_classstart_serializationfirst	enumeratestart_object_metaconcrete_modelr   remote_fieldZparent_linkZlocal_fields	serializeattnamehandle_fieldhandle_fk_fieldZlocal_many_to_manyhandle_m2m_field
end_objectr.   end_serializationgetvalue)r   Zquerysetr0   r1   r2   r3   r4   r5   r8   progress_barr+   objr@   r   Z	pk_parentfieldr   r   r   rB   K   s>    

 

zSerializer.serializec                 C   s   t ddS )zA
        Called when serializing of the queryset starts.
        zDsubclasses of Serializer must provide a start_serialization() methodNNotImplementedErrorr   r   r   r   r;   y   s    zSerializer.start_serializationc                 C   s   dS )z?
        Called when serializing of the queryset ends.
        Nr   rO   r   r   r   rH      s    zSerializer.end_serializationc                 C   s   t ddS )z>
        Called when serializing of an object starts.
        z=subclasses of Serializer must provide a start_object() methodNrM   r   rK   r   r   r   r>      s    zSerializer.start_objectc                 C   s   dS )z<
        Called when serializing of an object ends.
        Nr   rP   r   r   r   rG      s    zSerializer.end_objectc                 C   s   t ddS )zW
        Called to handle each individual (non-relational) field on an object.
        z=subclasses of Serializer must provide a handle_field() methodNrM   r   rK   rL   r   r   r   rD      s    zSerializer.handle_fieldc                 C   s   t ddS )z6
        Called to handle a ForeignKey field.
        z@subclasses of Serializer must provide a handle_fk_field() methodNrM   rQ   r   r   r   rE      s    zSerializer.handle_fk_fieldc                 C   s   t ddS )z5
        Called to handle a ManyToManyField.
        zAsubclasses of Serializer must provide a handle_m2m_field() methodNrM   rQ   r   r   r   rF      s    zSerializer.handle_m2m_fieldc                 C   s    t t| jddr| j S dS )zn
        Return the fully serialized queryset (or None if the output stream is
        not seekable).
        rI   N)callablegetattrr0   rI   rO   r   r   r   rI      s    zSerializer.getvalue)r   r   r	   r
   Zinternal_use_onlyr   r:   r   r9   rB   r;   rH   r>   rG   rD   rE   rF   rI   r   r   r   r   r/   @   s"     .r/   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	Deserializerz+
    Abstract base deserializer class.
    c                 K   s&   || _ t|trt|| _n|| _dS )zA
        Init this serializer given a stream or a string
        N)r8   
isinstancestrr   r0   )r   Zstream_or_stringr8   r   r   r   r      s    
zDeserializer.__init__c                 C   s   | S r   r   rO   r   r   r   __iter__   s    zDeserializer.__iter__c                 C   s   t ddS )z9Iteration interface -- return the next item in the streamz;subclasses of Deserializer must provide a __next__() methodNrM   rO   r   r   r   __next__   s    zDeserializer.__next__N)r   r   r	   r
   r   rW   rX   r   r   r   r   rT      s   
rT   c                   @   s6   e Zd ZdZdddZdd Zddd	Zdd
dZdS )DeserializedObjectae  
    A deserialized model.

    Basically a container for holding the pre-saved deserialized data along
    with the many-to-many data saved with the object.

    Call ``save()`` to save the object (with the many-to-many data) to the
    database; call ``save(save_m2m=False)`` to save just the object fields
    (and not touch the many-to-many stuff.)
    Nc                 C   s   || _ || _|| _d S r   )objectm2m_datadeferred_fields)r   rK   r[   r\   r   r   r   r      s    zDeserializedObject.__init__c                 C   s   d| j j| jjj| jjf S )Nz<%s: %s(pk=%s)>)	__class__r   rZ   r?   labelr   rO   r   r   r   __repr__   s
    zDeserializedObject.__repr__Tc                 K   sV   t jj| jf|dd| | jrL|rL| j D ]\}}t| j|| q0d | _d S )NT)usingraw)r   ModelZ	save_baserZ   r[   itemsrS   set)r   Zsave_m2mr`   kwargsZaccessor_nameZobject_listr   r   r   save   s
    
zDeserializedObject.savec           	      C   s  i | _ | j D ]\}}| jj}|jd |j }t|jt	j
rzt|||dd}W n: tk
r } zt|j|| jj|jW 5 d }~X Y nX || j |j< qt|jt	jrzt|||dd}W n6 tk
r } zt||| jj|W 5 d }~X Y nX t| j|j| q|   d S )Nr$   F)handle_forward_references)r[   r\   rc   rZ   r?   Z	app_labelZ
model_namerU   rA   r   ZManyToManyReldeserialize_m2m_valuesr   r   r   r   r   nameZManyToOneReldeserialize_fk_value	ExceptionsetattrrC   rf   )	r   r`   rL   r   optsr^   valuesevaluer   r   r   save_deferred_fields   s"    *&z'DeserializedObject.save_deferred_fields)NN)TN)N)r   r   r	   r
   r   r_   rf   rq   r   r   r   r   rY      s
   

rY   c                 C   s   | j j}|| j jj}|dkrt|drt| dr| f | }z*| j j||j	| j|| j jj< W n | j
k
r   Y nX | f |S )z
    Build a model instance.

    If the model instance doesn't have a primary key and the model supports
    natural keys, try to retrieve it from the database.
    Nget_by_natural_keynatural_key)r?   default_managergetr   rC   hasattrrs   	to_python
db_managerrr   ZDoesNotExist)rb   datadbrt   r   rs   r   r   r   build_instance   s    r{   c           	   
      s   | j j t jdr$ fdd}n fdd}zt|}W n, tk
rh } zt||W 5 d }~X Y nX z"g }|D ]}||| qt|W S  tk
r } z(t	|t
r|rt W Y S t||W 5 d }~X Y nX d S )Nrr   c                    s:   t | dr(t| ts( jj|  jS  jj| S d S )NrW   )	rv   rU   rV   _default_managerrx   rr   r   r?   rw   )rp   r   r`   r   r   m2m_convert  s    z+deserialize_m2m_values.<locals>.m2m_convertc                    s    j j| S r   )r?   r   rw   )v)r   r   r   r~     s    )rA   r   rv   r|   iter	TypeErrorr   appendrk   rU   r   DEFER_FIELD)	rL   r   r`   rg   r~   Zpks_iterro   rn   r   r   r}   r   rh     s"    rh   c           	      C   s   |d krd S | j j}|j}| j j}t|drt|drt|tsz||j| }W n" t	k
rv   |rpt
 Y S  Y nX t||}|jjj r|j}|S |j||S )Nrr   rW   )rA   r   r|   
field_namerv   rU   rV   rx   rr   r   r   rS   r?   r   	get_fieldrw   )	rL   r   r`   rg   r   rt   r   rK   rp   r   r   r   rj   -  s*    


rj   N)r
   ior   Zdjango.core.exceptionsr   Z	django.dbr   rZ   r   KeyErrorr   rk   r   r   r   r   r/   rT   rY   r{   rh   rj   r   r   r   r   <module>   s   l9