U
    5iu/                     @   s   d Z ddlZddlmZ ddlmZ ddlmZ e Z	G dd d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.
    N)StringIO)ObjectDoesNotExist)modelsc                   @   s*   e Zd ZdZd	ddZdd Zdd ZdS )
PickleSerializerzd
    Simple wrapper around pickle to be used in signing.dumps()/loads() and
    cache backends.
    Nc                 C   s   |d krt jn|| _d S N)pickleHIGHEST_PROTOCOLprotocol)selfr	    r   @/tmp/pip-unpacked-wheel-gcyiijx6/django/core/serializers/base.py__init__   s    zPickleSerializer.__init__c                 C   s   t || jS r   )r   dumpsr	   r
   objr   r   r   r      s    zPickleSerializer.dumpsc                 C   s
   t |S r   )r   loads)r
   datar   r   r   r      s    zPickleSerializer.loads)N)__name__
__module____qualname____doc__r   r   r   r   r   r   r   r      s   
r   c                   @   s   e Zd ZdZdS )SerializerDoesNotExistz'The requested serializer was not found.Nr   r   r   r   r   r   r   r   r      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 r   )r   pk)r
   r   r"   r   r   r   r   4   s    z M2MDeserializationError.__init__N)r   r   r   r   r   r   r   r   r   r!   2   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   updateA   s    
*
zProgressBar.updateN)r   r   r   r1   r   r7   r   r   r   r   r#   9   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_classr9   Zselected_fieldsr;   r<   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_objectr7   end_serializationgetvalue)r
   Zquerysetr9   r:   r;   r<   r=   r>   rA   progress_barr4   r   rI   r"   Z	pk_parentfieldr   r   r   rK   [   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   rD      s    zSerializer.start_serializationc                 C   s   dS )z?
        Called when serializing of the queryset ends.
        Nr   rW   r   r   r   rQ      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() methodNrU   r   r   r   r   rG      s    zSerializer.start_objectc                 C   s   dS )z<
        Called when serializing of an object ends.
        Nr   r   r   r   r   rP      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() methodNrU   r
   r   rT   r   r   r   rM      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() methodNrU   rX   r   r   r   rN      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() methodNrU   rX   r   r   r   rO      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).
        rR   N)callablegetattrr9   rR   rW   r   r   r   rR      s    zSerializer.getvalue)r   r   r   r   Zinternal_use_onlyr#   rC   r   rB   rK   rD   rQ   rG   rP   rM   rN   rO   rR   r   r   r   r   r8   P   s"     .r8   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)rA   
isinstancestrr   r9   )r
   Zstream_or_stringrA   r   r   r   r      s    
zDeserializer.__init__c                 C   s   | S r   r   rW   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__() methodNrU   rW   r   r   r   __next__   s    zDeserializer.__next__N)r   r   r   r   r   r^   r_   r   r   r   r   r[      s   
r[   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
   r   rb   rc   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   ra   rH   labelr"   rW   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_basera   rb   itemsrZ   set)r
   Zsave_m2mrg   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)rb   rc   rj   ra   rH   Z	app_labelZ
model_namer\   rJ   r   ZManyToManyReldeserialize_m2m_valuesr!   r   r   r   r"   nameZManyToOneReldeserialize_fk_value	ExceptionsetattrrL   rm   )	r
   rg   rT   r   optsre   valuesevaluer   r   r   save_deferred_fields   s"    *&z'DeserializedObject.save_deferred_fields)NN)TN)N)r   r   r   r   r   rf   rm   rx   r   r   r   r   r`      s
   

r`   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)rH   default_managergetr"   rL   hasattrrz   	to_python
db_managerry   ZDoesNotExist)ri   r   dbr{   r"   rz   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 )Nry   c                    s:   t | dr(t| ts( jj|  jS  jj| S d S )Nr^   )	r}   r\   r]   _default_managerr   ry   r"   rH   r~   )rw   r   rg   r   r   m2m_convert$  s    z+deserialize_m2m_values.<locals>.m2m_convertc                    s    j j| S r   )rH   r"   r~   )v)r   r   r   r   *  s    )rJ   r   r}   r   iter	TypeErrorr!   appendrr   r\   r   DEFER_FIELD)	rT   r   rg   rn   r   Zpks_iterrv   ru   r"   r   r   r   ro   !  s"    ro   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 )Nry   r^   )rJ   r   r   
field_namer}   r\   r]   r   ry   r   r   rZ   rH   r"   	get_fieldr~   )	rT   r   rg   rn   r   r{   r   r   rw   r   r   r   rq   =  s*    


rq   )r   r   ior   Zdjango.core.exceptionsr   Z	django.dbr   ra   r   r   KeyErrorr   rr   r   r   r!   r#   r8   r[   r`   r   ro   rq   r   r   r   r   <module>   s"   l9