
    h                         d 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mZ dd	lmZ dd
lmZ ddlmZ d Z G d de      Z G d de      Zy)a  
Copy of ``django.contrib.admin.utils.get_deleted_objects`` and a subclass of
``django.contrib.admin.utils.NestedObjects`` that work with django-polymorphic
querysets.
Ultimately these should go directly into django-polymorphic or, in a more
generic way, into Django itself.

This code has been copied from Django 1.9.4.

At all locations where something has been changed, there are inline comments
in the code.
    )defaultdict)VERSION)quote)get_permission_codename)models)	Collector)NoReverseMatchreverse)	force_str)format_html)capfirstc                 z   t        |      }|j                  |        t               fd}|j                  |      }|j                  D cg c]
  } ||       }	}|j
                  j                         D 
 ci c]%  \  }
} |
j                  j                  t        |       ' }}
} |||	fS c c}w c c} }
w )a  
    Find all objects related to ``objs`` that should also be deleted. ``objs``
    must be a homogeneous iterable of objects (e.g. a QuerySet).
    Returns a nested list of strings suitable for display in the
    template with the ``unordered_list`` filter.
    )usingc                 &   | j                   j                  v }| j                  }t        |j                        dt        |       }|r	 t        j                  d|j                  d|j                  dd t        | j                               f      }|j                  dt        d|      }j                  |      sj                  |j                         t!        dt        |j                        ||       S |S # t        $ r |cY S w xY w)Nz: :__change.deletez{}: <a href="{}">{}</a>)	__class__	_registry_metar   verbose_namer   r
   name	app_label
model_namer   _get_pk_valr	   r   has_permaddr   )	obj	has_adminoptsno_edit_link	admin_urlp
admin_siteperms_neededusers	         O/home/dcms/DCMS/lib/python3.12/site-packages/filer/admin/patched/admin_utils.pyformat_callbackz,get_deleted_objects.<locals>.format_callback'   s    MMZ%9%99	yy#+D,=,=#>#,S>3 $#'1'+~~'+%8 %)51B+C*E	G	  >>28TBDA==#  !2!238'(9(9:("$ $  ! " $##$s   AD DD)
PolymorphicAwareNestedObjectscollectsetnested	protected
model_objsitemsr   verbose_name_plurallen)objsr"   r(   r&   r   	collectorr*   	to_deleter    r/   modelmodel_countr'   s     ``        @r)   get_deleted_objectsr9      s     .E:Id5L @   1I1:1D1DE#%EIEQZQeQeQkQkQmn+%5;;22CI=nKnk<:: Fns   B2?*B7c                   d     e Zd Z fdZd Zd
 fd	Zedk\  r fdZn fdZd ZddZ	d	 Z
 xZS )NestedObjectsc                 x    t        |   |i | i | _        t               | _        t        t              | _        y N)super__init__edgesr-   r/   r   r0   )selfargskwargsr   s      r)   r?   zNestedObjects.__init__P   s1    $)&)
%c*    c                 Z    | j                   j                  |g       j                  |       y r=   )r@   
setdefaultappend)rA   sourcetargets      r)   add_edgezNestedObjects.add_edgeV   s!    

fb)008rD   c                 
   |D ]  }|r^|j                  d      sM||j                  j                  |j                  j                  dz  }| j	                  t        ||      |       n| j	                  d |       | j                  |j                  j                     j                  |        	 t        | (  |fd|i|S # t        j                  $ r/}| j                  j                  |j                         Y d }~y d }~ww xY w)N+)classr   source_attr)endswithr   r   r   rJ   getattrr0   r7   r   r>   r,   r   ProtectedErrorr/   updateprotected_objects)	rA   r4   rH   rN   rC   r    related_nameer   s	           r)   r,   zNestedObjects.collectY   s     		6C;#7#7#<*#\\44!'!7!7.   gc<8#>dC(OOCIIOO,005		6	77?4K[KFKK$$ 	7NN!!!"5"566	7s   .C   D%C==D)      c                 ~    t         |   |||      } |j                  |D cg c]  }|j                   c} S c c}w r=   )r>   related_objectsselect_relatedr   )rA   related_modelrelated_fieldsr4   qsrelatedr   s         r)   rY   zNestedObjects.related_objectsj   s;    (MB$2$$>&Rw||&RSS&Rs   :c                 n    t         |   ||      }|j                  |j                  j                        S r=   )r>   rY   rZ   fieldr   )rA   r^   r4   r]   r   s       r)   rY   zNestedObjects.related_objectsn   s/    ($7B$$W]]%7%788rD   c                    ||v rg S |j                  |       g }| j                  j                  |d      D ]$  }|j                  | j	                  |||             & |r
 ||      g}n|g}|r|j                  |       |S )N )r   r@   getextend_nestedrG   )rA   r    seenr*   childrenchildrets          r)   re   zNestedObjects._nestedr   s    $;IZZ^^C, 	HEOODLLoFG	H"3'(C%CJJx 
rD   c                     t               }g }| j                  j                  dd      D ]$  }|j                  | j	                  |||             & |S )z4
        Return the graph as a nested list.
        Nrb   )r-   r@   rc   rd   re   )rA   r*   rf   rootsroots        r)   r.   zNestedObjects.nested   sN     uJJNN4, 	DDLLdD/BC	DrD   c                      y)z
        We always want to load the objects into memory so that we can display
        them to the user in confirm page.
        Frb   )rA   rB   rC   s      r)   can_fast_deletezNestedObjects.can_fast_delete   s    
 rD   )NNr=   )__name__
__module____qualname__r?   rJ   r,   DJANGO_VERSIONrY   re   r.   rn   __classcell__r   s   @r)   r;   r;   O   s6    +97  	T	9rD   r;   c                         e Zd Zd fd	Z xZS )r+   c                 |    t        |d      r|j                         j                         }t        |   |fd|i|S )Nnon_polymorphicrN   )hasattrrw   filterr>   r,   )rA   r4   rN   rC   r   s       r)   r,   z%PolymorphicAwareNestedObjects.collect   sK    4*+ '')002Dw5)5-35 	5rD   r=   )ro   rp   rq   r,   rs   rt   s   @r)   r+   r+      s    5 5rD   r+   N)__doc__collectionsr   djangor   rr   django.contrib.admin.utilsr   django.contrib.authr   	django.dbr   django.db.models.deletionr   django.urlsr	   r
   django.utils.encodingr   django.utils.htmlr   django.utils.textr   r9   r;   r+   rb   rD   r)   <module>r      sK    $ , , 7  / / + ) &2;jAI AH5M 5rD   