
    Nwg                        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
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 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' ddl(m)Z)m*Z* ddl+m,Z,m-Z- ddlm.Z. ddl/m0Z0m1Z1m2Z2 ddl3m4Z4m5Z5  ejl                  e7      Z8e8js                   ejt                                d Z; G d d      Z< G d de,      Z= G d d e=e-      Z>e>fd!Z?y)"    N)OrderedDict)deepcopy)escape)warn)diff_match_patch)settings)ImproperlyConfiguredValidationError)no_style)	Paginator)connectionsrouter)fields)
ForeignKey)QuerySet)TransactionManagementErrorset_rollback)	force_str)	mark_safe)gettext_lazy   )
exceptionswidgets)DeclarativeMetaclassModelDeclarativeMetaclass)Field)ErrorResult	RowResult)atomic_if_using_transactionget_related_modelc                 J    t        | d      xr t        | j                  d      S )z@
    Determine if a model has natural foreign key functions
    natural_keyget_by_natural_key)hasattrobjectsmodels    N/var/www/horilla/myenv/lib/python3.12/site-packages/import_export/resources.pyhas_natural_foreign_keyr*   "   s)     5-( W+.     c                   .    e Zd Zd Zd Zd Zed        Zy)Diffc                 V    t         j                  ||      | _        g | _        || _        y N)r-   _read_field_valuesleftrightnew)selfresourceinstancer3   s       r)   __init__zDiff.__init__,   s$    ++Hh?	
r+   c                 :    t         j                  ||      | _        y r/   )r-   r0   r2   )r4   r5   r6   s      r)   compare_withzDiff.compare_with1   s    ,,Xx@
r+   c                 X   g }t               }t        | j                  | j                        D ]z  \  }}||k7  r| j                  rd}|j                  t        |      t        |            }|j                  |       |j                  |      }t        |      }|j                  |       | |S )N )r   zipr1   r2   r3   	diff_mainr   diff_cleanupSemanticdiff_prettyHtmlr   append)r4   datadmpv1v2diffhtmls          r)   as_htmlzDiff.as_html4   s     $))TZZ0 	FBRxDHH==2	">D$$T*&&t,DT?DKK	 r+   c                 f    |j                         D cg c]  }|j                  |       c}S c c}w r/   )get_import_fieldsexport)clsr5   r6   fs       r)   r0   zDiff._read_field_valuesA   s(    ,4,F,F,HIq"IIIs   .N)__name__
__module____qualname__r7   r9   rG   classmethodr0    r+   r)   r-   r-   +   s(    
A J Jr+   r-   c                      e Zd ZdZd Zed        Zed        Zed        Zed        Z	ed        Z
d Zd	 Zd
 Zd Zd@dZd Zd Zd Zd Z	 dAdZ	 dAdZd@dZ	 dBdZd Zd Zd Zd Zd Zd Zd ZdCdZd Z d Z!d  Z"d! Z#d" Z$d@d#Z%d$ Z&d% Z'd& Z(d' Z)d( Z*d@d)Z+d* Z,dCd+Z-d, Z.	 	 	 	 	 dDd-Z/d. Z0d/ Z1d0 Z2d1 Z3d2 Z4d3 Z5d4 Z6d@d5Z7d@d6Z8d@d7Z9d8 Z:d9 Z;d@d:Z<d; Z=d< Z>d= Z?d> Z@d? ZAy)EResourcez
    Resource defines how objects are mapped to their import and export
    representations and handle importing and exporting data.
    c                 b    t        | j                        | _        g | _        g | _        g | _        y)z
        kwargs:
           An optional dict of kwargs.
           Subclasses can use kwargs to pass dynamic values to enhance import / exports.
        N)r   r   create_instancesupdate_instancesdelete_instancesr4   kwargss     r)   r7   zResource.__init__L   s.     t{{+ !# " "r+   c                     t         S )zJ
        Returns the class used to store the result of an import.
        )r   r4   s    r)   get_result_classzResource.get_result_class^   s	    
 r+   c                     t         S )zM
        Returns the class used to store the result of a row import.
        )r   r[   s    r)   get_row_result_classzResource.get_row_result_classe   s
    
 r+   c                     t         S )zT
        Returns the class used to store an error resulting from an import.
        )r   r[   s    r)   get_error_result_classzResource.get_error_result_classl   s	    
 r+   c                     t         S )zV
        Returns the class used to display the diff for an imported instance.
        )r-   r[   s    r)   get_diff_classzResource.get_diff_classs   s	    
 r+   c                     | j                   j                  )t        j                  | j                   j                        S | j                   j                  S r/   )_metausing_dbr   db_for_writer(   r[   s    r)   get_db_connection_namezResource.get_db_connection_namez   s=    ::&&&tzz'7'788::&&&r+   c                 |    | j                   j                  t        t        dd      S | j                   j                  S )NIMPORT_EXPORT_USE_TRANSACTIONST)rd   use_transactionsgetattrr   r[   s    r)   get_use_transactionszResource.get_use_transactions   s2    ::&&.8%EtLL::...r+   c                 |    | j                   j                  t        t        dd      S | j                   j                  S )NIMPORT_EXPORT_CHUNK_SIZEd   )rd   
chunk_sizerk   r   r[   s    r)   get_chunk_sizezResource.get_chunk_size   s2    ::  (8%?EE::(((r+   c                 l    t        dt        d       t        | j                  j	                               S )NzOThe 'get_fields()' method is deprecated and will be removed in a future release   
stacklevel)r   DeprecationWarninglistr   valuesrX   s     r)   
get_fieldszResource.get_fields   s/    "		
 DKK&&())r+   c                     | j                   j                         D ]  \  }}||k(  s|c S  t        d| d| j                   d      )z;
        Returns the field name for a given field.
        zField z does not exists in z	 resource)r   itemsAttributeError	__class__)r4   field
field_namerL   s       r)   get_field_namezResource.get_field_name   sX     "[[..0 	"MJEz!!	" UG//?yI
 	
r+   Nc                     t               )z|
        Initializes an object. Implemented in
        :meth:`import_export.resources.ModelResource.init_instance`.
        )NotImplementedErrorr4   rows     r)   init_instancezResource.init_instance   s    
 "##r+   c                     | j                         D cg c]  }| j                  |    }}|D ]  }|j                  |vs y |j                  |      S c c}w )zI
        Calls the :doc:`InstanceLoader <api_instance_loaders>`.
        N)get_import_id_fieldsr   column_nameget_instance)r4   instance_loaderr   rL   import_id_fieldsr~   s         r)   r   zResource.get_instance   sd     594M4M4OPqDKKNPP% 	E  + 	 ++C00 Qs   Ac                     | j                   j                  s| j                  ||      }|r|dfS | j                  |      dfS )zW
        Either fetches an already existing instance or initializes a new one.
        FT)rd   force_init_instancer   r   )r4   r   r   r6   s       r)   get_or_init_instancezResource.get_or_init_instance   sF     zz--((#>H&!!#&,,r+   c                 .    | j                   j                  S ) )rd   r   r[   s    r)   r   zResource.get_import_id_fields   s    zz***r+   c                 r    | j                   D cg c]  }|| j                  j                  vs| c}S c c}w )z
        Returns the fields to be included in calls to bulk_update().
        ``import_id_fields`` are removed because `id` fields cannot be supplied to
        bulk_update().
        )r   rd   r   )r4   rL   s     r)   get_bulk_update_fieldszResource.get_bulk_update_fields   s-      ;;Oa!4::3N3N*NOOOs   44c                 z   	 t        | j                        dkD  r@|s|rn;| j                  j                  j                  j                  | j                  |       | j                  j                          y# t        $ r}| j                  |||       Y d}~<d}~ww xY w# | j                  j                          w xY w)z=
        Creates objects by calling ``bulk_create``.
        r   
batch_sizeN)	lenrU   rd   r(   r&   bulk_create	Exceptionhandle_import_errorclearr4   using_transactionsdry_runraise_errorsr   resultes          r)   r   zResource.bulk_create   s    	*4(()A-)gJJ$$,,88--* 9  !!'')  	>$$VQ==	> !!'')s*   AA5 5	B>BB BB B:c                    	 t        | j                        dkD  rO|s|rnJ| j                  j                  j                  j                  | j                  | j                         |       | j                  j                          y# t        $ r}| j                  |||       Y d}~<d}~ww xY w# | j                  j                          w xY w)z=
        Updates objects by calling ``bulk_update``.
        r   r   N)
r   rV   rd   r(   r&   bulk_updater   r   r   r   r   s          r)   r   zResource.bulk_update   s    	*4(()A-)gJJ$$,,88--335#- 9  !!'')  	>$$VQ==	> !!'')s*   A'B 	B*B% B- %B**B- -C	c                    	 t        | j                        dkD  rf|s|rna| j                  D cg c]  }|j                   }}| j                  j                  j
                  j                  |      j                          | j                  j                          yc c}w # t        $ r}| j                  |||       Y d}~Ad}~ww xY w# | j                  j                          w xY w)z
        Deletes objects by filtering on a list of instances to be deleted,
        then calling ``delete()`` on the entire queryset.
        r   )pk__inN)r   rW   pkrd   r(   r&   filterdeleter   r   r   )r4   r   r   r   r   o
delete_idsr   s           r)   bulk_deletezResource.bulk_delete   s    

	*4(()A-)g040E0E!F1!$$!FJ!FJJ$$,,33:3FMMO !!'') "G 	>$$VQ==	> !!'')s;   +B  B A B  B   	C)C<C	 CC	 	C%c                    |i }n|j                         }| j                  j                  r"	 |j                  |j	                         |       |rt        |      y# t
        $ r}|j                  |      }Y d}~-d}~ww xY w)a  
        Takes any validation errors that were raised by
        :meth:`~import_export.resources.Resource.import_instance`, and combines them
        with validation errors raised by the instance's ``full_clean()``
        method. The combined errors are then re-raised as single, multi-field
        ValidationError.

        If the ``clean_model_instances`` option is False, the instances's
        ``full_clean()`` method is not called, and only the errors raised by
        ``import_instance()`` are re-raised.
        N)excludevalidate_unique)copyrd   clean_model_instances
full_cleankeysr
   update_error_dict)r4   r6   import_validation_errorsr   errorsr   s         r)   validate_instancezResource.validate_instance  s     $+F-224F::++5##"KKM$3 $  !&))  # 5,,V45s   !A 	B %A;;B c                 ^    | j                   ||fi | | j                  j                  r:|r| j                  j	                  |       nQ| j
                  j	                  |       n5| j                  |      s| j                  |      rn| j                  ||        | j                  ||fi | y)a  
        Takes care of saving the object to the database.

        Objects can be created in bulk if ``use_bulk`` is enabled.

        :param instance: The instance of the object to be persisted.

        :param is_create: A boolean flag to indicate whether this is a new object
                          to be created, or an existing object to be updated.

        :param row: A dict representing the import row.

        :param \**kwargs:
            See :meth:`import_row
        N)
before_save_instancerd   use_bulkrU   r@   rV   _is_using_transactions_is_dry_rundo_instance_saveafter_save_instance)r4   r6   	is_creater   rY   s        r)   save_instancezResource.save_instance"  s      	"!!(C:6:::%%,,X6%%,,X6..v64;K;KF;S%%h	:   39&9r+   c                 $    |j                          y)a  
        A method specifically to provide a single overridable hook for the instance
        save operation.
        For example, this can be overridden to implement update_or_create().

        :param instance: The model instance to be saved.
        :param is_create: A boolean flag to indicate whether this is a new object
                          to be created, or an existing object to be updated.
        N)save)r4   r6   r   s      r)   r   zResource.do_instance_save@  s     	r+   c                      ya  
        Override to add additional logic. Does nothing by default.

        :param instance: A new or existing model instance.

        :param row: A ``dict`` containing key / value data for the row to be imported.

        :param \**kwargs:
            See :meth:`import_row`
        NrQ   r4   r6   r   rY   s       r)   r   zResource.before_save_instanceL       	r+   c                      yr   rQ   r   s       r)   r   zResource.after_save_instanceY  r   r+   c                     | j                   ||fi | | j                  j                  r| j                  j	                  |       n3| j                  |      s| j                  |      rn|j                           | j                  ||fi | y)as  
        Calls :meth:`instance.delete` as long as ``dry_run`` is not set.
        If ``use_bulk`` then instances are appended to a list for bulk import.

        :param instance: A new or existing model instance.

        :param row: A ``dict`` containing key / value data for the row to be imported.

        :param \**kwargs:
            See :meth:`import_row`
        N)	before_delete_instancerd   r   rW   r@   r   r   r   after_delete_instancer   s       r)   delete_instancezResource.delete_instancef  s{     	$##Hc<V<::!!((2..v64;K;KF;S!"""8S;F;r+   c                      yr   rQ   r   s       r)   r   zResource.before_delete_instance}  r   r+   c                      yr   rQ   r   s       r)   r   zResource.after_delete_instance  r   r+   c                     |j                   st        j                  d| d       y|j                  |vr't        j                  d| d|j                   d       y |j                  |||fi | y)a  
        Handles persistence of the field data.

        :param field: A :class:`import_export.fields.Field` instance.

        :param instance: A new or existing model instance.

        :param row: A ``dict`` containing key / value data for the row to be imported.

        :param is_m2m: A boolean value indicating whether or not this is a
          many-to-many field.

        :param \**kwargs:
            See :meth:`import_row`
        zskipping field 'z"' - field attribute is not definedNz' - column name 'z' is not present in row)	attributeloggerdebugr   r   )r4   r~   r6   r   is_m2mrY   s         r)   import_fieldzResource.import_field  s|      LL+E72TUVC'LL"5' *""'"3"3!44KM 

8S&3F3r+   c                    g }| j                         D ]o  }|| j                  v r|j                  | j                  |          0| j                  j                         D ]#  }|j                  |k(  s|j                  |       % q |S r/   )get_import_orderr   r@   rx   r   )r4   import_fieldsr   r~   s       r)   rI   zResource.get_import_fields  s    //1 		JT[[($$T[[%<= ++- $$
2!((/		 r+   c                 ~    t        dt        d       |du r|j                  d|i        | j                  ||fi | y )NzThe 'import_obj' method is deprecated and will be replaced with 'import_instance(self, instance, row, **kwargs)' in a future release.  Refer to Release Notes for details.rs   rt   Tr   )r   rv   updateimport_instance)r4   objrA   r   rY   s        r)   
import_objzResource.import_obj  sI    H 	
 d?MM9g./S$1&1r+   c                 4   i }| j                         D ]=  }t        |j                  t        j                        r(	  | j
                  |||fi | ? |rt        |      y# t        $ r-}t        t        |      d      ||j                  <   Y d}~d}~ww xY w)a  
        Traverses every field in this Resource and calls
        :meth:`~import_export.resources.Resource.import_field`. If
        ``import_field()`` results in a ``ValueError`` being raised for
        one of more fields, those errors are captured and reraised as a single,
        multi-field ValidationError.

        :param instance: A new or existing model instance.

        :param row: A ``dict`` containing key / value data for the row to be imported.

        :param \**kwargs:
            See :meth:`import_row`
        invalid)codeN)
rI   
isinstancewidgetr   ManyToManyWidgetr   
ValueErrorr
   r   r   )r4   r6   r   rY   r   r~   r   s          r)   r   zResource.import_instance  s     ++- 	XE%,,(@(@AX!!!%3A&A		X !&))   X*9)A,Y*Wu'Xs   A!!	B*#BBc                    | j                  |      }| j                  |      }|s|s| j                  j                  ry| j	                         D ];  }t        |j                  t        j                        s(| j                  |||d       = y)af  
        Saves m2m fields.

        Model instance need to have a primary key value before
        a many-to-many relationship can be used.

        :param instance: A new or existing model instance.

        :param row: A ``dict`` containing key / value data for the row to be imported.

        :param \**kwargs:
            See :meth:`import_row`
        TN)
r   r   rd   r   rI   r   r   r   r   r   )r4   r6   r   rY   r   r   r~   s          r)   save_m2mzResource.save_m2m  s~     "88@""6*"w4::3F3F //1 >!%,,0H0HI!!%3=>r+   c                      y)aG  
        Returns ``True`` if ``row`` importing should delete instance.

        Default implementation returns ``False``.
        Override this method to handle deletion.

        :param row: A ``dict`` containing key / value data for the row to be imported.

        :param instance: A new or existing model instance.
        FrQ   )r4   r   r6   s      r)   
for_deletezResource.for_delete  s     r+   c                 z   | j                   j                  r| j                   j                  s|ry| j                         D ]  }t	        |j
                  t        j                        r|j                  |j                         vrDt        |j                  |            }|j                  g n't        |j                  |      j                               }t        |      t        |      k7  r yt!        d |D              t!        d |D              k7  s y|j                  |      |j                  |      k7  s y y)a  
        Returns ``True`` if ``row`` importing should be skipped.

        Default implementation returns ``False`` unless skip_unchanged == True
        and skip_diff == False.

        If skip_diff is True, then no comparisons can be made because ``original``
        will be None.

        When left unspecified, skip_diff and skip_unchanged both default to ``False``,
        and rows are never skipped.

        By default, rows are not skipped if validation errors have been detected
        during import.  You can change this behavior and choose to ignore validation
        errors by overriding this method.

        Override this method to handle skipping rows meeting certain
        conditions.

        Use ``super`` if you want to preserve default handling while overriding
        ::

            class YourResource(ModelResource):
                def skip_row(self, instance, original,
                             row, import_validation_errors=None):
                    # Add code here
                    return super().skip_row(instance, original, row,
                                            import_validation_errors=import_validation_errors)

        :param instance: A new or updated model instance.

        :param original: The original persisted model instance.

        :param row: A ``dict`` containing key / value data for the row to be imported.

        :param import_validation_errors: A ``dict`` containing key / value data for any
          identified validation errors.
        Fc              3   4   K   | ]  }|j                     y wr/   r   .0vs     r)   	<genexpr>z$Resource.skip_row.<locals>.<genexpr>K  s     81!$$8   c              3   4   K   | ]  }|j                     y wr/   r   r   s     r)   r   z$Resource.skip_row.<locals>.<genexpr>K  s      CADDCr   T)rd   skip_unchanged	skip_diffrI   r   r   r   r   r   r   rw   cleanr   	get_valueallr   sorted)r4   r6   originalr   r   r~   instance_valuesoriginal_valuess           r)   skip_rowzResource.skip_row  s   P 

))zz##'++- 	!E %,,(@(@A$$CHHJ6 #'u{{3'7"8"++-B48Q8U8U8W3X   '3+?? 888F C"1C =  !??8,0II -	!. r+   c                 n    | j                         D cg c]  }t        |j                         c}S c c}w )z.
        Diff representation headers.
        )rI   r   r   )r4   r~   s     r)   get_diff_headerszResource.get_diff_headersT  s,     ;?:P:P:RS	%++,SSSs   2c                      y)z
        Override to add additional logic. Does nothing by default.

        :param dataset: A ``tablib.Dataset``.

        :param \**kwargs:
            See :meth:`import_row`
        NrQ   )r4   datasetrY   s      r)   before_importzResource.before_importZ       	r+   c                      y)a6  
        Override to add additional logic. Does nothing by default.

        :param dataset: A ``tablib.Dataset``.

        :param result: A :class:`import_export.results.Result` implementation
          containing a summary of the import.

        :param \**kwargs:
            See :meth:`import_row`
        NrQ   )r4   r   r   rY   s       r)   after_importzResource.after_importe       	r+   c                      y)z
        Override to add additional logic. Does nothing by default.

        :param row: A ``dict`` containing key / value data for the row to be imported.

        :param \**kwargs:
            See :meth:`import_row`
        NrQ   )r4   r   rY   s      r)   before_import_rowzResource.before_import_rows  r   r+   c                      y)aY  
        Override to add additional logic. Does nothing by default.

        :param row: A ``dict`` containing key / value data for the row to be imported.

        :param row_result: A ``RowResult`` instance.
          References the persisted ``instance`` as an attribute.

        :param \**kwargs:
            See :meth:`import_row`
        NrQ   )r4   r   
row_resultrY   s       r)   after_import_rowzResource.after_import_row~  r   r+   c                 |    t        dt        d       ||j                  d|i        | j                  ||d fi | y )NzThe 'after_import_instance' method is deprecated and will be replaced with 'after_init_instance(self, instance, new, row, **kwargs)' in a future release.  Refer to Release Notes for details.rs   rt   
row_number)r   rv   r   after_init_instance)r4   r6   r3   r  rY   s        r)   after_import_instancezResource.after_import_instance  sJ    H 	
 !MM<45   3??r+   c                      y)ar  
        Override to add additional logic. Does nothing by default.

        :param instance: A new or existing model instance.

        :param new: a boolean flag indicating whether instance is new or existing.

        :param row: A ``dict`` containing key / value data for the row to be imported.

        :param \**kwargs:
            See :meth:`import_row`
        NrQ   )r4   r6   r3   r   rY   s        r)   r  zResource.after_init_instance  s     	r+   c                     t         j                  ||       |r%|j                   | j                         |             |rt	        j
                  |      y )Nexc_info)r   r   append_base_errorr`   r   ImportError)r4   r   errorr   s       r)   r   zResource.handle_import_error  sM    UU+$$%BT%@%@%B5%IJ((// r+   c           	      ^   | j                   j                  }| j                   j                  s!|j                  dd      | j                   _         | j	                                }| j                   j
                  r||_        d}	  | j                  |fi | | j                  ||      \  }} | j                  |||fi | |rt        j                  |_        nt        j                  |_        |s#t        |      } | j                         | ||      }	| j!                  ||      r|r,t        j"                  |_        |sP	j%                  | d       n<t        j&                  |_        |j)                  |       | j                   j                  rt        |      |_         | j,                  ||fi | |s	j%                  | d       ni }
	  | j.                  ||fi | | j5                  ||||
      rt        j"                  |_        n;| j7                  ||
        | j8                  |||fi |  | j:                  ||fi | |j)                  |       | j                   j                  r||_        |s	j%                  | |       |s||_        |s+| j                   j>                  s	jA                         |_!         | jD                  ||fi | |S # t0        $ r}|j3                  |
      }
Y d}~d}~ww xY w# t0        $ r'}t        jF                  |_        ||_$        Y d}~|S d}~wtJ        $ r|}t        jL                  |_        tO        |tP              stR        jU                  |d       |jV                  jY                   | j[                         |||d                Y d}~|S d}~ww xY w)aZ  
        Imports data from ``tablib.Dataset``. Refer to :doc:`import_workflow`
        for a more complete description of the whole import process.

        :param row: A ``dict`` of the 'row' to import.
          A row is a dict of data fields so can be a csv line, a JSON object,
          a YAML object etc.

        :param instance_loader: The instance loader to be used to load the model
          instance associated with the row (if there is one).

        :param \**kwargs:
            See below.

        :Keyword Arguments:
            * dry_run (``boolean``) --
              A True value means that no data should be persisted.
            * use_transactions (``boolean``) --
              A True value means that transactions will be rolled back.
            * row_number  (``int``) --
              The index of the row being imported.
        retain_instance_in_row_resultFNTr  r  )r   number).rd   r   store_instancegetr^   store_row_values
row_valuesr  r   r  r   IMPORT_TYPE_NEWimport_typeIMPORT_TYPE_UPDATEr   rb   r   IMPORT_TYPE_SKIPr9   IMPORT_TYPE_DELETEadd_instance_infor6   r   r   r
   r   r   r   r   r   r   skip_html_diffrG   rE   r  IMPORT_TYPE_INVALIDvalidation_errorr   IMPORT_TYPE_ERRORr   r   r   r   r   r@   r`   )r4   r   r   rY   r   r  r   r6   r3   rE   r   r   s               r)   
import_rowzResource.import_row  sX   . JJ((	zz(((.

/)DJJ% 1T..02
::&&$'J!B	"D""31&1 55osKMHc$D$$XsCB6B)2)B)B
&)2)E)E
&#H-,t**,T8SAsH--6-G-GJ*$))$5-6-I-IJ*00:zz00.6x.@
+(D((3A&A$))$5+-((D((3A&A ==8S:RS-6-G-GJ***85MN&D&&xcDVD!DMM(C:6:,,X6::,,*2J' %%dH5.6
+TZZ%>%>"&,,.
!D!!#z<V< O '  01/B/B00,	4  	,%.%B%BJ"*+J''   	%.%@%@J" a!;<Q.$$-++-aSAUV  	sQ   EK9 
K C1K9 	K6K1+K9 1K66K9 9	N,L$$N,0A1N''N,c                 H   || j                         }| j                         }t        |   }	t        |	j                  dd      }
|r|
st
        |xs |xr |
}| j                  j                  Ht        | j                  j                  t              r| j                  j                  dk  rt        d      t        ||      5   | j                  |||||fi |}|r1|s"|j                         s|r|j                         rt        d|       |cddd       S # 1 sw Y   yxY w)a  
        Imports data from ``tablib.Dataset``. Refer to :doc:`import_workflow`
        for a more complete description of the whole import process.

        :param dataset: A ``tablib.Dataset``.

        :param raise_errors: Whether errors should be printed to the end user
                             or raised regularly.

        :param use_transactions: If ``True`` the import process will be processed
                                 inside a transaction.

        :param collect_failed_rows:
          If ``True`` the import process will create a new dataset object comprising
          failed rows and errors.
          This can be useful for debugging purposes but will cause higher memory usage
          for larger datasets.
          See :attr:`~import_export.results.Result.failed_dataset`.

        :param rollback_on_validation_errors: If both ``use_transactions`` and
          ``rollback_on_validation_errors`` are set to ``True``, the import process will
          be rolled back in case of ValidationError.

        :param dry_run: If ``dry_run`` is set, or an error occurs, if a transaction
            is being used, it will be rolled back.

        :param \**kwargs:
            Metadata which may be associated with the import.
        Nsupports_transactionsFr   z%Batch size must be a positive integerusingT)rl   rg   r   rk   featuresr	   rd   r   r   intr   r    import_data_inner
has_errorshas_validation_errorsr   )r4   r   r   r   rj   collect_failed_rowsrollback_on_validation_errorsrY   db_connection
connectionr$  r   r   s                r)   import_datazResource.import_data  s&   P ##88:335 /
 '!8%!
 $9&&.9'T?T::  ,4::00#6$**:O:ORS:SDEE();=Q 	+T++"# F "$$&1f6R6R6TT7	 	 	s   ADD!c           	      ^
    | j                                }| j                         |_        t        |      |_        | j                         }	 t        ||      5   | j                  |fi | d d d        | j                  |j                         | j                  j                  | |      }
t        |      |_        |r|j                  |j                         t        |d      D ]   \  }}t!        t#        |j                  |            }t        |xr | j                  j$                   |      5  |j'                  |||d        | j(                  ||
fi |}d d d        | j                  j$                  r/t        | j*                        | j                  j,                  k(  r@t        ||      5  | j/                  |||| j                  j,                  |       d d d        t        | j0                        | j                  j,                  k(  r@t        ||      5  | j3                  |||| j                  j,                  |       d d d        t        | j4                        | j                  j,                  k(  r+t        ||      5  | j7                  ||||       d d d        |j9                         |j:                  ro|j=                  |||j:                         |r|j?                  ||j:                  d          |rtA        jB                  |j:                  d   jD                  ||      |jF                  r_|jI                  |||jF                         |r|j?                  ||jF                         |r"tA        jB                  |jF                  ||      |jJ                  tL        jN                  k7  s| j                  jP                  s|jS                  |        | j                  j$                  rUt        ||      5  | j/                  ||||       | j3                  ||||       | j7                  ||||       d d d        	 t        ||      5   | jT                  ||fi | d d d        |S # 1 sw Y   xY w# t        $ r}	| j                  ||	|       Y d }	~	 d }	~	ww xY w# 1 sw Y   _xY w# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   @xY w# 1 sw Y   xY w# 1 sw Y   |S xY w# t        $ r}	| j                  ||	|       Y d }	~	|S d }	~	ww xY w)	Nr%  r   )r   r   r  )r   r   )r   r   )r  r   )+r\   r   diff_headersr   
total_rowsrg   r    r   _check_import_id_fieldsheadersr   r   rd   instance_loader_classadd_dataset_headers	enumerater   r<   r   r   r"  rU   r   r   rV   r   rW   r   increment_row_result_totalr   append_error_rowappend_failed_rowr   r  r  r   append_invalid_rowr  r   r  report_skippedappend_row_resultr   )r4   r   r   r   r   r,  rY   r   r.  r   r   idata_rowr   r  s                  r)   r)  zResource.import_data_innerb  s    )&&(*"335L335	>,-?}U 6"""75f56((9 **::4I  L&&w7$Wa0 I	5KAxc'//8<=C,">4::+>+>'>m  #*.@&' -T__# 
 zz"" t,,-1F1FF4*- 	 ((.#('+zz'<'<#) ) 	 t,,-1F1FF4*- 	 ((.#('+zz'<'<#) ) 	 t,,-1F1FF4*-  ((.f )  --j9  ''3
0A0AB&,,S*2C2CA2FG$00"))"-33A3  ,,))!S*2M2MN&,,S*2M2MN$00"33A3  &&)*D*DD::,,((4SI	5V ::,-?}U 	  &f !    &f !    &f ! 		>,-?}U =!!!'6<V<=
 Y6 6  	>$$VQ==	> (	 		 	 B	 	=
   	>$$VQ==	>s   R R-#R 1*R83+S+SSA S,T "S87T RR 	R5R00R58S	S	S	S)	,S58T=T T 	T,T''T,c                 $    | j                  d      S )Nimport_order_get_ordered_field_namesr[   s    r)   r   zResource.get_import_order      ,,^<<r+   c                 $    | j                  d      S )Nexport_orderrD  r[   s    r)   get_export_orderzResource.get_export_order  rF  r+   c                      y)z
        Override to add additional logic. Does nothing by default.

        :param queryset: The queryset for export.

        :param \**kwargs:
            Metadata which may be associated with the export.
        NrQ   r4   querysetrY   s      r)   before_exportzResource.before_export  r   r+   c                      y)a  
        Override to add additional logic. Does nothing by default.

        :param queryset: The queryset for export.

        :param dataset: A ``tablib.Dataset``.

        :param \**kwargs:
            Metadata which may be associated with the export.
        NrQ   )r4   rL  r   rY   s       r)   after_exportzResource.after_export  r   r+   c                     |S )z
        Override to filter an export queryset.

        :param queryset: The queryset for export.

        :param \**kwargs:
            Metadata which may be associated with the export.

        :returns: The filtered queryset.
        rQ   rK  s      r)   filter_exportzResource.filter_export  s	     r+   c                     | j                  |      }|j                  |      }t        |      r|}nt        | |d       }| ||      S  |j                  |fi |S r/   )r   get_dehydrate_methodcallablerk   rJ   )r4   r~   r6   rY   r   dehydrate_methodmethods          r)   export_fieldzResource.export_field
  sg    ((/
 55jA$%%FT#3T:F(##u||H///r+   c                     |r|n| j                   }g }| j                         }|D ],  }||v s| j                  |      }||j                  |       . |S r/   )r   rI  _select_fieldr@   )r4   selected_fieldsfields_export_fieldsrH  r   r~   s          r)   get_export_fieldszResource.get_export_fields  se    %4/$++,,.& 	0JW$**:6$!((/		0
 r+   c                 r    | j                  |      }|D cg c]  } | j                  ||fi | c}S c c}w r/   )r]  rW  )r4   r6   rZ  rY   r\  r~   s         r)   export_resourcezResource.export_resource"  s;    ..?JWX!!!%<V<XXXs   4c                 z    | j                  |      }|D cg c]  }|st        |j                         c}S c c}w r/   )r]  r   r   )r4   rZ  r\  r~   s       r)   get_export_headerszResource.get_export_headers&  s3    ..?:GQ5	%++,QQQs   88c                 "    | j                         S r/   )rI   r[   s    r)   get_user_visible_fieldsz Resource.get_user_visible_fields*  s    %%''r+   c              #     K   t        |t              s|E d {    y |j                  rx|j                  j                  s|j	                  d      }t        || j                               }t        |j                        D ]  }|j                  |dz         E d {      y |j                  | j                               E d {    y 7 7 27 	w)Nr   r   )rp   )r   r   _prefetch_related_lookupsqueryorder_byr   rq   range	num_pagesget_pageiterator)r4   rL  	paginatorindexs       r)   iter_querysetzResource.iter_queryset-  s     (H-// >>** $,,T2!(D,?,?,ABIy223 9$--eai8889  ((D4G4G4I(JJJ   9Js4   CCBCC*CCCCCc                     | j                   |fi | || j                         } | j                  |fi |}|j                  dd      }| j	                  |      }t        j                  |      }| j                  |      D ](  } | j                  |fd|i|}|j                  |       *  | j                  ||fi | |S )z
        Exports a resource.

        :param queryset: The queryset for export (optional).

        :returns: A ``tablib.Dataset``.
        Nr\  )rZ  )r6  rZ  )rM  get_querysetrQ  r  ra  tablibDatasetrn  r_  r@   rO  )r4   rL  rY   r\  r6  r   r   rs           r)   rJ   zResource.export>  s     	8.v.((*H%4%%h9&9

?D9))-)H..1%%h/ 	C$$$SR-R6RANN1	 	(G6v6r+   c                     || j                   v r| j                   |   S | j                   j                         D ]  \  }}||j                  k(  s|c S  t        d| d       y )Nz,cannot identify field for export with name '')r   r{   r   r   )r4   target_field_namer   r~   s       r)   rY  zResource._select_fieldW  sh    +;;011!%!2!2!4 	J E$5$55	
 	;<M;NaPQr+   c                    t        t        | j                  |      xs d      }|t        t        | j                  d      xs d      z   }g }|D cg c]  }||vs|j                  |       c} g }| j                  j                         D ]*  \  }}||vs|j                  |vs|j                  |       , t        |      t        |      z   S c c}w )zP
        Return a list of field names, respecting any defined ordering.
        rQ   r   )tuplerk   rd   r@   r   r{   r   )	r4   order_fieldorder_fieldsdefined_fieldsorderrL   declared_fieldsr   r~   s	            r)   rE  z!Resource._get_ordered_field_namesc  s    
 WTZZ=CD%gdjj(.K.Qr(RR"0CQAUNaC!%!2!2!4 	3J&5+<+<E+I&&z2	3 U|eO444 	Ds   	CCc                 &    |j                  dd      S )Nr   Fr  rX   s     r)   r   zResource._is_using_transactionst  s    zz.66r+   c                 &    |j                  dd      S )Nr   Fr  rX   s     r)   r   zResource._is_dry_runw  s    zz)U++r+   c                 $   g }g }g }| j                         dgk(  ry| j                         D ]@  }|| j                  vr|j                  |       #|j                  | j                  |          B |r0t        j                  t        ddj                  |      z              |D ]9  }|r|j                  |vst        |j                        }|j                  |       ; |r0t        j                  t        ddj                  |      z              y)ay  
        Provides a safety check with a meaningful error message for cases where
        the ``import_id_fields`` declaration contains a field which is not in the
        dataset.  For most use-cases this is an error, so we detect and raise.
        There are conditions, such as 'dynamic fields' where this does not apply.
        See issue 1834 for more information.
        idNzfThe following fields are declared in 'import_id_fields' but are not present in the resource fields: %sz, zcThe following fields are declared in 'import_id_fields' but are not present in the file headers: %s)	r   r   r@   r   
FieldError_joinr   r   )r4   r6  r   missing_fieldsmissing_headersr   r~   cols           r)   r5  z Resource._check_import_id_fieldsz  s&    $$&4&0335 	AJ,%%j1 ''J(?@		A ''Aii/0  & 	,Ee//w>U../&&s+		, ''>ii01  r+   r/   )NN)NT)F)FFNFF)BrM   rN   rO   __doc__r7   rP   r\   r^   r`   rb   rg   rl   rq   ry   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rI   r   r   r   r   r   r   r   r   r  r  r	  r  r   r"  r0  r)  r   rI  rM  rO  rQ  rW  r]  r_  ra  rc  rn  rJ   rY  rE  r   r   r5  rQ   r+   r)   rS   rS   F   s   
#$         ' '/)*	
$1-+P RV*( RV***$ HL*<:<
<.46
2*4>6DLT		
@0fV !&+JX{z==	0	YR(K"2
R5"7,,r+   rS   )	metaclassc                      e Zd ZdZeZi dddddddej                  dej                  d	ej                  d
ej                  dej                  dej                  dej                  dej                  dej                  dej                  dej                  dej                  dej                  dej                  ej                  ej                  ej                  ej                  ej                   dZed        Zed        Zeej*                  fd       Zed        Zed        Zd Zd dZd Zed        Zy)!ModelResourcezH
    ModelResource is Resource subclass for handling Django models.
    ManyToManyFieldget_m2m_widgetOneToOneFieldget_fk_widgetr   	CharFieldDecimalFieldDateTimeField	DateField	TimeFieldDurationField
FloatFieldIntegerFieldPositiveIntegerFieldBigIntegerFieldPositiveBigIntegerFieldPositiveSmallIntegerFieldSmallIntegerFieldSmallAutoField)	AutoFieldBigAutoFieldNullBooleanFieldBooleanField	JSONFieldc                 ^    t        j                  t        j                  t	        |            S )z.
        Prepare widget for m2m field
        r'   )	functoolspartialr   r   r!   )rK   r~   s     r)   r  zModelResource.get_m2m_widget  s(    
   $$,=e,D
 	
r+   c                     t        |      }t        |      xr | j                  j                  }t	        j
                  t        j                  ||      S )z6
        Prepare widget for fk and o2o fields
        )r(   use_natural_foreign_keys)r!   r*   rd   r  r  r  r   ForeignKeyWidget)rK   r~   r(   r  s       r)   r  zModelResource.get_fk_widget  sP     "%( $E*Qsyy/Q/Q 	!   $$%=
 	
r+   c                 4   |}d}t        t        |dd            r|j                         }|| j                  v r3| j                  |   }t	        |t
              r t        | |      |      }|S |j                  j                  D ]W  }|j                  | j                  v s| j                  |j                     }t	        |t
              r t        | |      |      } n 	 ddl	m
} t	        ||      rt        j                  S |S # t        $ r  G d d      }Y 3w xY w)a	  
        Returns the widget that would likely be associated with each
        Django type.

        Includes mapping of Postgres Array field. In the case that
        psycopg2 is not installed, we consume the error and process the field
        regardless.
        r;   get_internal_typeNr   )
ArrayFieldc                       e Zd Zy):ModelResource.widget_from_django_field.<locals>.ArrayFieldN)rM   rN   rO   rQ   r+   r)   r  r    s    r+   r  )rT  rk   r  WIDGETS_MAPr   strr}   __mro__rM   django.contrib.postgres.fieldsr  r  r   SimpleArrayWidget)rK   rL   defaultr   internal_type
base_classr  s          r)   widget_from_django_fieldz&ModelResource.widget_from_django_field  s    GA2D9://1MCOO+__]3F&#&-f-a0. #  kk11 
&&#//9 __Z-@-@AF!&#.!5f!5a!8E !Z(000   s   D DDc                 0   i }| j                   j                  r7| j                   j                  j                  |i       }|j                  |       t	        |j
                  t        j                        r"|j                  du r|j                  ddd       |S )z=
        Returns widget kwargs for given field_name.
        T)coerce_to_stringallow_blank)	rd   r   r  r   
issubclassr}   r   r  blank)rK   r   django_fieldwidget_kwargs
cls_kwargss        r)   widget_kwargs_for_fieldz%ModelResource.widget_kwargs_for_field  s}    
 99**..z2>J  ,|--v/?/?@""d*  d4!PQr+   c           	         | j                  |      }| j                  ||      }|}|}t        |t              r$d|vr | j                  j
                  s
|dz  }d|d<   | j                  || |di |||j                        }|S )zU
        Returns a Resource Field instance for the given Django model field.
        ___idT	key_is_id)r   r   r   readonlyr  rQ   )r  r  r   r   rd   r  DEFAULT_RESOURCE_FIELDr  )	rK   r   r  r  FieldWidgetr  r   r   r~   s	            r)   field_from_django_fieldz%ModelResource.field_from_django_field  s     22<@33JM	  |Z0K'II66I)-M+&**#// (( + 
 r+   c                 ^    | j                   j                  j                  j                         S )z
        Returns a queryset of all objects for this model. Override this if you
        want to limit the returned queryset.
        )rd   r(   r&   r   r[   s    r)   rp  zModelResource.get_queryset<  s#    
 zz''++--r+   Nc                 6    | j                   j                         S )z1
        Initializes a new Django model.
        )rd   r(   r   s     r)   r   zModelResource.init_instanceC  s     zz!!r+   c                    | j                  |      }|st        d |j                  D              r| j                         }t        |   }|j
                  j                  t               | j                  j                  g      }|r;|j                         }	 |D ]  }	|j                  |	        	 |j                          yyyy# |j                          w xY w)zH
        Reset the SQL sequences after new objects are imported
        c              3   V   K   | ]!  }|j                   t        j                  k(   # y wr/   )r  r   r  )r   rs  s     r)   r   z-ModelResource.after_import.<locals>.<genexpr>O  s$      
;<AMMY666
s   ')N)r   anyrowsrg   r   opssequence_reset_sqlr   rd   r(   cursorexecuteclose)
r4   r   r   rY   r   r.  r/  sequence_sqlr  lines
             r)   r   zModelResource.after_importI  s    
 ""6*3 
@F
 
 !779M$]3J%>><<
TZZ--.L #**,# , -t,- LLN 
w LLNs   C Cc                 r    t        | j                  d      r| j                  j                  S | j                  S )Nname)r%   rd   r  rM   )rK   s    r)   get_display_namezModelResource.get_display_name_  s(    399f%99>>!||r+   r/   )rM   rN   rO   r  r   r  r   
CharWidgetDecimalWidgetDateTimeWidget
DateWidget
TimeWidgetDurationWidgetFloatWidgetIntegerWidgetBooleanWidget
JSONWidgetr  rP   r  r  Widgetr  r  r  rp  r   r   r  rQ   r+   r)   r  r    s    #+ 	o 	W''	
 	-- 	// 	W'' 	W'' 	// 	g)) 	-- 	 5 5 	700 	"7#8#8 	$W%:%:  	W22!" 	'//#$ **--#11--''-K2 
 
 
 
" 18 ( (T    8."#,  r+   r  c                 v    d| i}t        dt        f|      }| j                  dz   }d|i}t        } |||f|      S )zN
    Factory for creating ``ModelResource`` class for given Django model.
    r(   MetarS   )typeobjectrM   r   )r(   resource_classattrsr  
class_nameclass_attrsr  s          r)   modelresource_factoryr  f  sS     eE	5)D*,J 	K *IZ.!2K@@r+   )@r  loggingcollectionsr   r   r   rF   r   warningsr   rq  r   django.confr   django.core.exceptionsr	   r
   django.core.management.colorr   django.core.paginatorr   	django.dbr   r   django.db.modelsr   django.db.models.fields.relatedr   django.db.models.queryr   django.db.transactionr   r   django.utils.encodingr   django.utils.safestringr   django.utils.translationr   r  r;   r   r   declarativer   r   r   resultsr   r   r   utilsr    r!   	getLoggerrM   r   
addHandlerNullHandlerr*   r-   rS   r  r  rQ   r+   r)   <module>r     s      #     -   H 1 + ) # 6 + J + - 6 ! H  - - A			8	$   %'%%' (J J6`- `F#zH(A zz 1> Ar+   