
    h5;                        d 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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 ddlm Z  ddl!m"Z"  G d de#      Z$ G d de#      Z% G d dejL                        Z'y)z<
The parent admin displays the list view of the base model.
    )admin)AdminErrorList	AdminForm)add_preserved_filters)ContentType)ImproperlyConfiguredPermissionDenied)models)Http404HttpResponseRedirect)TemplateResponse)URLResolver)	force_str)	urlencode)	mark_safe)gettext_lazy)get_base_polymorphic_model   )PolymorphicModelChoiceFormc                       e Zd ZdZy)RegistrationClosed:The admin model can't be registered anymore at this point.N__name__
__module____qualname____doc__     M/home/dcms/DCMS/lib/python3.12/site-packages/polymorphic/admin/parentadmin.pyr   r      s    @r   r   c                       e Zd ZdZy)ChildAdminNotRegisteredz/The admin site for the model is not registered.Nr   r   r   r    r"   r"      s    5r   r"   c                        e Zd ZdZdZdZdZdZeZ	dZ
 fdZd Zd Zd Zd	 Zdd
ZddZd fd	Z fdZddZd Zd fd	ZddZddZ fdZ fdZd ZddZddZed        Z xZ S )PolymorphicParentModelAdmina  
    A admin interface that can displays different change/delete pages, depending on the polymorphic model.
    To use this class, one attribute need to be defined:

    * :attr:`child_models` should be a list models.

    Alternatively, the following methods can be implemented:

    * :func:`get_child_models` should return a list of models.
    * optionally, :func:`get_child_type_choices` can be overwritten to refine the choices for the add dialog.

    This class needs to be inherited by the model admin base class that is registered in the site.
    The derived models should *not* register the ModelAdmin, but instead it should be returned by :func:`get_child_models`.
    NFz(\d+|__fk__)c                 v    t        |   ||g|i | d| _        | j                  t	        |      | _        y y )NF)super__init__	_is_setup
base_modelr   )selfmodel
admin_siteargskwargs	__class__s        r    r'   z$PolymorphicParentModelAdmin.__init__A   s>    
<T<V<??"8?DO #r   c                     | j                   ry | j                         | _        | j                  r2t        | j                  d   t        j
                        st        d      | j                  | _        d| _         y )Nr   zSince django-polymorphic 1.4, the `child_models` attribute and `get_child_models()` method should be a list of models only.
The model-admin class should be registered in the regular Django admin.T)	r(   get_child_models_child_models
issubclassr
   Modelr   r,   _child_admin_siter*   s    r    _lazy_setupz'PolymorphicParentModelAdmin._lazy_setupH   sh    >>!224
 j1C1CA1F&U&Z  "&r   c                    | j                   rt        d      t        || j                        s.t	        |j
                   d| j                  j
                         t        |t        j                        s2t	        |j
                   dt        j                  j
                         | j                  j                  ||       y)z9
        Register a model with admin to display.
        r   z should be a subclass of N)
r(   r   r3   r)   	TypeErrorr   r   
ModelAdminr5   register)r*   r+   model_admins      r    register_childz*PolymorphicParentModelAdmin.register_child[   s     >>$%abb%1u~~..GH`H`Gabcc+u'7'78''((A%BRBRB[B[A\]  	''{;r   c                 H    | j                   t        d      | j                   S )aS  
        Return the derived model classes which this admin should handle.
        This should return a list of tuples, exactly like :attr:`child_models` is.

        The model classes can be retrieved as ``base_model.__subclasses__()``,
        a setting in a config file, or a query of a plugin registration system at your option
        z,Implement get_child_models() or child_models)child_modelsNotImplementedErrorr6   s    r    r1   z,PolymorphicParentModelAdmin.get_child_modelsm   s(     $%&TUU   r   c                 n   | j                          g }t        j                  j                  | j	                         ddi}|j                         D ]b  \  }}d| d}| j                  |      }t        ||      }	 |	|      s2|j                  |j                  |j                  j                  f       d |S )zw
        Return a list of polymorphic types for which the user has the permission to perform the given action.
        for_concrete_modelsFhas__permission)r7   r   objectsget_for_modelsr1   items_get_real_admin_by_modelgetattrappendid_metaverbose_name)
r*   requestactionchoicescontent_typesr+   ctperm_function_namer<   perm_functions
             r    get_child_type_choicesz2PolymorphicParentModelAdmin.get_child_type_choicesz   s     	#++::""$
:?
 ',,. 	>IE2#'x{!;77>K#K1CDM )NNBEE5;;#;#;<=	> r   c                     	 | j                   j                  j                         j                  d      j	                  |      }| j                  |d   |      S # | j                   j
                  $ r t        w xY w)Npolymorphic_ctypepksuper_if_self)r+   rE   non_polymorphicvaluesgetDoesNotExistr   _get_real_admin_by_ct)r*   	object_idr[   objs       r    _get_real_adminz+PolymorphicParentModelAdmin._get_real_admin   s|    	

""224;;<OPTTXaTb 
 ))#.A*BR_)`` zz&& 	M	s   AA  A;c                 "   	 t         j                  j                  |      }|j                         }|s%|j                         \  }}t	        d| d| d      | j                  ||      S # t         j                  $ r}t	        |      d }~ww xY w)NzNo model found for '.'.rZ   )r   rE   
get_for_idr_   r   model_classnatural_keyrH   )r*   ct_idr[   rR   erh   	app_labelr+   s           r    r`   z1PolymorphicParentModelAdmin._get_real_admin_by_ct   s    	$$//6B nn&!~~/Iu01UG2FGG,,[,VV '' 	!*	s   A+ +B>B		Bc                     || j                   vrt        d| d      	 | j                  j                  |   }|r|| u r
t               S |S # t        $ r t        d| d      w xY w)NzInvalid model 'z(', it must be registered as child model.z*No child admin site was registered for a 'z' model.)r2   r	   r5   	_registryKeyErrorr"   r&   )r*   rh   r[   
real_adminr/   s       r    rH   z4PolymorphicParentModelAdmin._get_real_admin_by_model   s     d000"!+.VW 	 //99+FJ Z4/7N  	)<[MR 	s   A A$c                 ^    t         |   |      }| j                  s|j                         }|S N)r&   get_querysetpolymorphic_listr\   )r*   rN   qsr/   s      r    rs   z(PolymorphicParentModelAdmin.get_queryset   s.    W!'*$$##%B	r   c                    t        |j                  j                  dd            }|s| j                  |      S | j	                  |      }t        t        d|i      | j                  j                  d|      }|j                  |||      S )z(Redirect the add view to the real admin.rj   r   )preserved_filtersopts)
intGETr^   add_type_viewr`   r   r   r+   rL   add_view)r*   rN   form_urlextra_contextrj   rp   s         r    r|   z$PolymorphicParentModelAdmin.add_view   s    GKKOOGQ/0%%g..33E:J,)2GU3C)D JJ,, H &&w-HHr   c                 R    | j                  |      } |j                  ||g|i |S )z+Redirect the change view to the real admin.)rc   change_view)r*   rN   ra   r-   r.   rp   s         r    r   z'PolymorphicParentModelAdmin.change_view   s1    )))4
%z%%gyJ4J6JJr   c                     |r(| j                  |      } |j                  ||g|i |S t        |   ||g|i |S rr   )rc   changeform_viewr&   )r*   rN   ra   r-   r.   rp   r/   s         r    r   z+PolymorphicParentModelAdmin.changeform_view   sU     --i8J-:--gyR4R6RR 7*7IOOOOr   c                 L    | j                  |      }|j                  |||      S )z,Redirect the history view to the real admin.)r~   )rc   history_viewr*   rN   ra   r~   rp   s        r    r   z(PolymorphicParentModelAdmin.history_view   s*    )))4
&&w	&WWr   c                 J    | j                  |      }|j                  |||      S )z+Redirect the delete view to the real admin.)rc   delete_viewr   s        r    r   z'PolymorphicParentModelAdmin.delete_view   s'    )))4
%%gy-HHr   c                 H   d|j                   v r|j                   j                         |_         |j                   j                  d      }|j                  d      }|D ](  }|j                  d      }|d   |j                   |d   <   * |j                   d= t        |   |      S )N_changelist_filters&=r   r   )rz   copyr^   splitr&   get_preserved_filters)r*   rN   filtersfxcr/   s         r    r   z1PolymorphicParentModelAdmin.get_preserved_filters   s     GKK/!++**,GKkkoo&;<Gc"A )GGCL$%aDAaD!) 12w,W55r   c                 D    t         |          }| j                          |S )zQ
        Expose the custom URLs for the subclasses and the URL resolver.
        )r&   get_urlsr7   )r*   urlsr/   s     r    r   z$PolymorphicParentModelAdmin.get_urls   s%     w! 	r   c                 >   t        |j                  j                  dd            }|sh	 |j                  d      }|dk(  rt        |      }nt        |d|       }| j                  j                  j                  dd	      j                  |
      }| j                  |      }t        d|j                        }|j                  |      }|st        d| d       |j                  |g|j                  i |j                  S # t        $ r t        d| d      w xY w)zI
        Forward any request to a custom view of the real admin.
        rj   r   /z<No ct_id parameter, unable to find admin subclass for path 'rf   polymorphic_ctype_idT)flatrX   ^zNo match for path 'z' in admin subclass.)ry   rz   r^   find
ValueErrorr   r+   rE   values_listr`   r   r   resolvefuncr-   r.   )	r*   rN   pathrj   posra   rp   resolverresolvermatchs	            r    subclass_viewz)PolymorphicParentModelAdmin.subclass_view  s*    GKKOOGQ/0	iin"9 #D	I #D3K 0I JJ&&223IPT2UYY Z E //6
sJOO4 ((./v5IJKK!}!!'WM,>,>W-BVBVWW  RSWRXXZ[ s   0D Dc                 |   | j                  |      st        d}|j                  d   rdt        |j                  d          }| j	                  |d      }t        |      dk(  rt        t        |      dk(  rt        d|d   d    |       S | j                  |j                  dk(  r|j                  nd	d
|d   d   i      }||j                  d
   _        |j                         rt        d|j                  d
    |       S d	ddiff}t        ||i |       }| j                  |j                  z   }| j                   j"                  }	t%        d      t        |	j&                        z  |d|j                  v xs d|j(                  v t+        |      t-        |d      |	j.                  d}
| j1                  ||
|      S )zI
        Display a choice form to select which page type to add.
         QUERY_STRINGr   addr   r   z?ct_id=POSTNrj   )datainitialfields)rj   )r<   zAdd %s_popupr   )title	adminformis_popupmediaerrorsrl   )has_add_permissionr	   METAr   rU   lenr   add_type_formmethodr   r   rP   is_validcleaned_datar   r   r+   rL   _rM   rz   r   r   rl   render_add_type_form)r*   rN   r}   extra_qsrP   form	fieldsets	adminFormr   rx   contexts              r    r{   z)PolymorphicParentModelAdmin.add_type_view!  s    &&w/""<<' 9W\\.%ABCDH--gu=w<1""w<1'''!*Q-
(KLL !!!(6!9tgajm, " 
 (/G$==?''$2C2CG2L1MhZ(XYY Xz235	dIrtD	

Y__,zz x[9T->->#??"!W\\1LX5Lu%$T2.
 (('8DDr   c                 v   | j                   j                  }|j                  }|j                  | j	                  |      t        |      |d| j                  d       | j                  xs) d| d|j                  j                          dd| dddg}| j                  j                  |_        t        |||      S )z3
        Render the page type choice form.
        T)has_change_permissionr}   rx   r   save_on_topadmin/r   z/add_type_form.htmlz$admin/polymorphic/add_type_form.htmlzadmin/add_type_form.html)r+   rL   rl   updater   r   r   add_type_templateobject_namelowerr,   namecurrent_appr   )r*   rN   r   r}   rx   rl   	templatess          r    r   z0PolymorphicParentModelAdmin.render_add_type_formO  s     zzNN	)-)C)CG)L%h/#//	
 ** 
YKq!1!1!7!7!9 ::MNYK232&	/
	 #oo22G<<r   c                 $   | j                   j                  }|j                  }| j                  j                  }|j                  }d| d|j                  j                          dd| dd| d|j                  j                          dd| ddgS )Nr   r   z/change_list.htmlzadmin/change_list.html)r+   rL   rl   r)   r   r   )r*   rx   rl   	base_optsbase_app_labels        r    change_list_templatez0PolymorphicParentModelAdmin.change_list_templatei  s    zzNN	 OO))	",, YKq!1!1!7!7!9 ::KLYK01^$Ai&;&;&A&A&C%DDUV^$$56$
 	
r   )T)r   Nrr   )r   )!r   r   r   r   r)   r?   rt   r   r   r   pk_regexr'   r7   r=   r1   rU   rc   r`   rH   rs   r|   r   r   r   r   r   r   r   r{   r   propertyr   __classcell__)r/   s   @r    r$   r$       s      J L .M
 H@&<$!&aW,I$K
	PX
I
	6	X<,E\=4 
 
r   r$   N)(r   django.contribr   django.contrib.admin.helpersr   r   ,django.contrib.admin.templatetags.admin_urlsr   "django.contrib.contenttypes.modelsr   django.core.exceptionsr   r	   	django.dbr
   django.httpr   r   django.template.responser   django.urlsr   django.utils.encodingr   django.utils.httpr   django.utils.safestringr   django.utils.translationr   r   polymorphic.utilsr   formsr   RuntimeErrorr   r"   r:   r$   r   r   r    <module>r      sg    ! B N : I  5 5 # + ' - 6 8 -A A6l 6Y
%"2"2 Y
r   