
u^Ԯ                 @   s  d  d l  m Z d  d l m Z d  d l m Z d  d l m Z 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 m Z m Z d  d
 l m Z m Z m Z d  d l m Z d  d l m Z d  d l m Z d d   Z  d d   Z! d d   Z" d d   Z# Gd d   d  Z$ Gd d   d e$  Z% Gd d   d e$  Z& d d   Z' d d   Z( d  d!   Z) d" S)#    )chain)apps)settings)NotRelationFieldflattenget_fields_from_path)checks)FieldDoesNotExist)models)
LOOKUP_SEP)
CombinableFOrderBy)BaseModelFormBaseModelFormSet_get_foreign_key)engines)DjangoTemplates)import_stringc             C   s.   y t  |  |  SWn t k
 r) d SYn Xd S)zX
    issubclass() variant that doesn't raise an exception if cls isn't a
    class.
    FN)
issubclass	TypeError)clsZ	classinfo r   =/tmp/pip-build-8lau8j11/django/django/contrib/admin/checks.py_issubclass   s    r   c             C   s\   t  |   } xI | D]A } y t  |  } Wn t k
 r@ w Yn Xt | |  r d Sq Wd S)z|
    Return whether or not a dotted class path (or a subclass of that class) is
    found in a list of candidate paths.
    TF)r   ImportErrorr   )Z
class_pathZcandidate_pathsr   pathZcandidate_clsr   r   r   _contains_subclass    s    r   c             K   sA   d d l  m } g  } x$ | D] } | j | j |    q W| S)Nr   )	all_sites)Zdjango.contrib.admin.sitesr   extendcheck)Zapp_configskwargsr   errorssiter   r   r   check_admin_app1   s
    r$   c              K   s  t  j d  s g  Sg  } d! } xG | D]? \ } } t  j |  s& | j t j d | d	 d
 |  q& Wx3 t j   D] } t | t  rv | j	 } Pqv Wd } | s | j t j d d	 d  nh d | j
 k rt d t j  r| j t j d d	 d  d | j
 k r,| j t j d d	 d  t d t j  sZ| j t j d d	 d  t d t j  s| j t j d d	 d  t d t j  s| j t j d d	 d  | S)"zF
    Check that the admin's dependencies are correctly installed.
    zdjango.contrib.admindjango.contrib.contenttypes  django.contrib.auth  django.contrib.messages  zE'%s' must be in INSTALLED_APPS in order to use the admin application.idz	admin.E%dNzA 'django.template.backends.django.DjangoTemplates' instance must be configured in TEMPLATES in order to use the admin application.z
admin.E403z+django.contrib.auth.context_processors.authz)django.contrib.auth.backends.ModelBackendz'django.contrib.auth.context_processors.auth' must be enabled in DjangoTemplates (TEMPLATES) if using the default auth backend in order to use the admin application.z
admin.E402z3django.contrib.messages.context_processors.messagesz'django.contrib.messages.context_processors.messages' must be enabled in DjangoTemplates (TEMPLATES) in order to use the admin application.z
admin.E404z7django.contrib.auth.middleware.AuthenticationMiddlewarezv'django.contrib.auth.middleware.AuthenticationMiddleware' must be in MIDDLEWARE in order to use the admin application.z
admin.E408z4django.contrib.messages.middleware.MessageMiddlewarezs'django.contrib.messages.middleware.MessageMiddleware' must be in MIDDLEWARE in order to use the admin application.z
admin.E409z4django.contrib.sessions.middleware.SessionMiddlewarezs'django.contrib.sessions.middleware.SessionMiddleware' must be in MIDDLEWARE in order to use the admin application.z
admin.E410r%   r&   r'   r(   r)   r*   )r,   r-   r.   )r   Zis_installedappendr   Errorr   all
isinstancer   engineZcontext_processorsr   r   ZAUTHENTICATION_BACKENDSZ
MIDDLEWARE)r!   r"   Zapp_dependenciesZapp_nameZ
error_coder3   Zdjango_templates_instancer   r   r   check_dependencies9   sZ      	




r4   c               @   sT  e  Z 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 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# d$   Z d% d&   Z d' d(   Z d) d*   Z d+ d,   Z d- d.   Z d/ d0   Z d1 d2   Z d3 d4   Z d5 d6   Z d7 S)8BaseModelAdminChecksc             K   s   |  j  |  |  j |  |  j |  |  j |  |  j |  |  j |  |  j |  |  j |  |  j |  |  j	 |  |  j
 |  |  j |  |  j |   S)N)_check_autocomplete_fields_check_raw_id_fields_check_fields_check_fieldsets_check_exclude_check_form_check_filter_vertical_check_filter_horizontal_check_radio_fields_check_prepopulated_fields_check_view_on_site_url_check_ordering_check_readonly_fields)self	admin_objr!   r   r   r   r       s    zBaseModelAdminChecks.checkc                sj   t    j t t f  s4 t d d d d   d d St t j    f d d   t   j  D   Sd	 S)
zV
        Check that `autocomplete_fields` is a list or tuple of model fields.
        za list or tupleoptionautocomplete_fieldsobjr+   z
admin.E036c                s/   g  |  ]% \ } }  j    | d  |   q S)zautocomplete_fields[%d])_check_autocomplete_fields_item).0index
field_name)rG   rC   r   r   
<listcomp>   s   	zCBaseModelAdminChecks._check_autocomplete_fields.<locals>.<listcomp>N)r2   rF   listtuplemust_ber   from_iterable	enumerate)rC   rG   r   )rG   rC   r   r6      s
    	z/BaseModelAdminChecks._check_autocomplete_fieldsc             C   s1  y | j  j j |  } Wn1 t k
 rL t d | d | d | d d  SYn X| j r t | t j  r t	 d d | d | d d S| j
 j j | j j   } | d k r t j d	 | j j  j t |  j f d | j d d
 g S| j s)t j d | j j t |  j f d | j d d g Sg  Sd S)z
        Check that an item in `autocomplete_fields` is a ForeignKey or a
        ManyToManyField and that the item has a related ModelAdmin with
        search_fields defined.
        fieldrE   rG   r+   z
admin.E037z%a foreign key or a many-to-many fieldz
admin.E038NzXAn admin for model "%s" has to be registered to be referenced by %s.autocomplete_fields.z
admin.E039zR%s must define "search_fields", because it's referenced by %s.autocomplete_fields.z
admin.E040)model_meta	get_fieldr	   refer_to_missing_fieldmany_to_manyr2   r
   
ForeignKeyrO   
admin_site	_registrygetremote_fieldr   r0   __name__type	__class__search_fields)rC   rG   rK   labelrR   Zrelated_adminr   r   r   rH      s0    $	
			
z4BaseModelAdminChecks._check_autocomplete_fields_itemc                sj   t    j t t f  s4 t d d d d   d d St t j    f d d   t   j  D   Sd	 S)
z\ Check that `raw_id_fields` only contains field names that are listed
        on the model. za list or tuplerE   raw_id_fieldsrG   r+   z
admin.E001c             3   s.   |  ]$ \ } }  j    | d  |  Vq d S)zraw_id_fields[%d]N)_check_raw_id_fields_item)rI   rJ   rK   )rG   rC   r   r   	<genexpr>   s   z<BaseModelAdminChecks._check_raw_id_fields.<locals>.<genexpr>N)r2   rb   rM   rN   rO   r   rP   rQ   )rC   rG   r   )rG   rC   r   r7      s
    	z)BaseModelAdminChecks._check_raw_id_fieldsc             C   s   y | j  j j |  } Wn1 t k
 rL t d | d | d | d d  SYn> X| j r t | t j  r t	 d d | d | d d Sg  Sd S)	z Check an item of `raw_id_fields`, i.e. check that field named
        `field_name` exists in model `model` and is a ForeignKey or a
        ManyToManyField. rR   rE   rG   r+   z
admin.E002z%a foreign key or a many-to-many fieldz
admin.E003N)
rS   rT   rU   r	   rV   rW   r2   r
   rX   rO   )rC   rG   rK   ra   rR   r   r   r   rc      s    $z.BaseModelAdminChecks._check_raw_id_fields_itemc                s     j  d k r g  St   j  t t f  sG t d d d d   d d S  j ro t j d d   j d d	 g St	   j   } t
 |  t
 t |   k r t j d
 d   j d d g St t j    f d d     j  D   S)z Check that `fields` only refer to existing fields, doesn't contain
        duplicates. Check if at most one of `fields` and `fieldsets` is defined.
        Nza list or tuplerE   fieldsrG   r+   z
admin.E004z,Both 'fieldsets' and 'fields' are specified.z
admin.E005z2The value of 'fields' contains duplicate field(s).z
admin.E006c             3   s$   |  ] }  j    | d   Vq d S)re   N)_check_field_spec)rI   rK   )rG   rC   r   r   rd     s   z5BaseModelAdminChecks._check_fields.<locals>.<genexpr>)re   r2   rM   rN   rO   	fieldsetsr   r0   r_   r   lensetr   rP   )rC   rG   re   r   )rG   rC   r   r8      s$    		
	
	z"BaseModelAdminChecks._check_fieldsc                s     j  d k r g  St   j  t t f  sG t d d d d   d d Sg   t t j     f d d	   t   j   D   Sd S)
zT Check that fieldsets is properly formatted and doesn't contain
        duplicates. Nza list or tuplerE   rg   rG   r+   z
admin.E007c             3   s1   |  ]' \ } }  j    | d  |   Vq d S)zfieldsets[%d]N)_check_fieldsets_item)rI   rJ   fieldset)rG   seen_fieldsrC   r   r   rd     s   z8BaseModelAdminChecks._check_fieldsets.<locals>.<genexpr>)rg   r2   rM   rN   rO   r   rP   rQ   )rC   rG   r   )rG   rl   rC   r   r9     s    	z%BaseModelAdminChecks._check_fieldsetsc                s  t  | t t f  s1 t d d   d  d d St |  d k r_ t d d   d  d d St  | d	 t  s t d
 d d   d  d d Sd | d	 k r t j d   d  j d d g St  | d	 d t t f  st d d d   d  d d S| j	 t
 | d	 d   t |  t t |   k r^t j d   d  j d d g St t j     f d d   | d	 d D   S)z~ Check an item of `fieldsets`, i.e. check that this is a pair of a
        set name and a dictionary containing "fields" key. za list or tuplerE   rG   r+   z
admin.E008   zof length 2z
admin.E009   za dictionaryz%s[1]z
admin.E010re   z3The value of '%s[1]' must contain the key 'fields'.z
admin.E011z%s[1]['fields']z(There are duplicate field(s) in '%s[1]'.z
admin.E012c             3   s(   |  ] }  j   | d     Vq d S)z%s[1]["fields"]N)rf   )rI   Zfieldset_fields)ra   rG   rC   r   r   rd   4  s   z=BaseModelAdminChecks._check_fieldsets_item.<locals>.<genexpr>)r2   rM   rN   rO   rh   dictr   r0   r_   r   r   ri   r   rP   )rC   rG   rk   ra   rl   r   )ra   rG   rC   r   rj     s,     
	
 
	
	z*BaseModelAdminChecks._check_fieldsets_itemc                sX   t  | t  rA t t j     f d d   t |  D   S j  |    Sd S)z `fields` should be an item of `fields` or an item of
        fieldset[1]['fields'] for any `fieldset` in `fieldsets`. It should be a
        field name or a tuple of field names. c             3   s4   |  ]* \ } }  j   | d    | f  Vq d S)z%s[%d]N)_check_field_spec_item)rI   rJ   rK   )ra   rG   rC   r   r   rd   ?  s   z9BaseModelAdminChecks._check_field_spec.<locals>.<genexpr>N)r2   rN   rM   r   rP   rQ   rp   )rC   rG   re   ra   r   )ra   rG   rC   r   rf   8  s
    	z&BaseModelAdminChecks._check_field_specc             C   s   | | j  k r g  Sy | j j j |  } Wn t k
 rD g  SYnS Xt | t j  r | j j	 j j
 r t j d | | f d | j d d g Sg  Sd  S)NzvThe value of '%s' cannot include the ManyToManyField '%s', because that field manually specifies a relationship model.rG   r+   z
admin.E013)readonly_fieldsrS   rT   rU   r	   r2   r
   ManyToManyFieldr\   ZthroughZauto_createdr   r0   r_   )rC   rG   rK   ra   rR   r   r   r   rp   E  s    		
z+BaseModelAdminChecks._check_field_spec_itemc             C   s   | j  d k r g  St | j  t t f  sG t d d d d | d d St | j   t t | j    k r t j d d | j	 d d	 g Sg  Sd S)
z6 Check that exclude is a sequence without duplicates. Nza list or tuplerE   excluderG   r+   z
admin.E014z3The value of 'exclude' contains duplicate field(s).z
admin.E015)
rs   r2   rM   rN   rO   rh   ri   r   r0   r_   )rC   rG   r   r   r   r:   a  s    $	
z#BaseModelAdminChecks._check_excludec          	   C   s9   t  | j t  s1 t d d d d d | d d  Sg  Sd S)	z+ Check that form subclasses BaseModelForm. parentr   rE   formrG   r+   z
admin.E016N)r   ru   r   must_inherit_from)rC   rG   r   r   r   r;   s  s    z BaseModelAdminChecks._check_formc                sj   t    j t t f  s4 t d d d d   d d St t j    f d d   t   j  D   Sd	 S)
z: Check that filter_vertical is a sequence of field names. za list or tuplerE   filter_verticalrG   r+   z
admin.E017c             3   s.   |  ]$ \ } }  j    | d  |  Vq d S)zfilter_vertical[%d]N)_check_filter_item)rI   rJ   rK   )rG   rC   r   r   rd     s   z>BaseModelAdminChecks._check_filter_vertical.<locals>.<genexpr>N)r2   rw   rM   rN   rO   r   rP   rQ   )rC   rG   r   )rG   rC   r   r<   {  s
    	z+BaseModelAdminChecks._check_filter_verticalc                sj   t    j t t f  s4 t d d d d   d d St t j    f d d   t   j  D   Sd	 S)
z< Check that filter_horizontal is a sequence of field names. za list or tuplerE   filter_horizontalrG   r+   z
admin.E018c             3   s.   |  ]$ \ } }  j    | d  |  Vq d S)zfilter_horizontal[%d]N)rx   )rI   rJ   rK   )rG   rC   r   r   rd     s   z@BaseModelAdminChecks._check_filter_horizontal.<locals>.<genexpr>N)r2   ry   rM   rN   rO   r   rP   rQ   )rC   rG   r   )rG   rC   r   r=     s
    	z-BaseModelAdminChecks._check_filter_horizontalc             C   sz   y | j  j j |  } Wn1 t k
 rL t d | d | d | d d  SYn* X| j sr t d d | d | d d Sg  Sd S)	z Check one item of `filter_vertical` or `filter_horizontal`, i.e.
        check that given field exists and is a ManyToManyField. rR   rE   rG   r+   z
admin.E019za many-to-many fieldz
admin.E020N)rS   rT   rU   r	   rV   rW   rO   )rC   rG   rK   ra   rR   r   r   r   rx     s    $	z'BaseModelAdminChecks._check_filter_itemc                sd   t    j t  s. t d d d d   d d St t j    f d d     j j   D   Sd	 S)
z, Check that `radio_fields` is a dictionary. za dictionaryrE   radio_fieldsrG   r+   z
admin.E021c             3   sA   |  ]7 \ } }  j    | d    j   | d |  Vq d S)rz   zradio_fields["%s"]N)_check_radio_fields_key_check_radio_fields_value)rI   rK   val)rG   rC   r   r   rd     s   z;BaseModelAdminChecks._check_radio_fields.<locals>.<genexpr>N)r2   rz   ro   rO   rM   r   rP   items)rC   rG   r   )rG   rC   r   r>     s
    	z(BaseModelAdminChecks._check_radio_fieldsc             C   s   y | j  j j |  } Wn1 t k
 rL t d | d | d | d d  SYnI Xt | t j  pe | j s t	 j
 d | | f d | j d d g Sg  Sd S)	z Check that a key of `radio_fields` dictionary is name of existing
        field and that the field is a ForeignKey or has `choices` defined. rR   rE   rG   r+   z
admin.E022zsThe value of '%s' refers to '%s', which is not an instance of ForeignKey, and does not have a 'choices' definition.z
admin.E023N)rS   rT   rU   r	   rV   r2   r
   rX   choicesr   r0   r_   )rC   rG   rK   ra   rR   r   r   r   r{     s    $	
z,BaseModelAdminChecks._check_radio_fields_keyc             C   sS   d d l  m } m } | | | f k rK t j d | d | j d d g Sg  Sd S)z5 Check type of a value of `radio_fields` dictionary. r   )
HORIZONTALVERTICALzDThe value of '%s' must be either admin.HORIZONTAL or admin.VERTICAL.rG   r+   z
admin.E024N)django.contrib.admin.optionsr   r   r   r0   r_   )rC   rG   r}   ra   r   r   r   r   r   r|     s    
	
z.BaseModelAdminChecks._check_radio_fields_valuec             C   sJ   t  | j  rB t | j t  rB t j d d | j d d g Sg  Sd  S)NzBThe value of 'view_on_site' must be a callable or a boolean value.rG   r+   z
admin.E025)callableZview_on_siter2   boolr   r0   r_   )rC   rG   r   r   r   r@     s    #	
z,BaseModelAdminChecks._check_view_on_site_urlc                sd   t    j t  s. t d d d d   d d St t j    f d d     j j   D   Sd	 S)
zZ Check that `prepopulated_fields` is a dictionary containing allowed
        field types. za dictionaryrE   prepopulated_fieldsrG   r+   z
admin.E026c             3   sA   |  ]7 \ } }  j    | d    j   | d |  Vq d S)r   zprepopulated_fields["%s"]N)_check_prepopulated_fields_key _check_prepopulated_fields_value)rI   rK   r}   )rG   rC   r   r   rd     s   zBBaseModelAdminChecks._check_prepopulated_fields.<locals>.<genexpr>N)r2   r   ro   rO   rM   r   rP   r~   )rC   rG   r   )rG   rC   r   r?     s
    	z/BaseModelAdminChecks._check_prepopulated_fieldsc             C   s   y | j  j j |  } Wn1 t k
 rL t d | d | d | d d  SYnO Xt | t j t j t j	 f  r t
 j d | | f d | j d d g Sg  Sd S)	z Check a key of `prepopulated_fields` dictionary, i.e. check that it
        is a name of existing field and the field is one of the allowed types.
        rR   rE   rG   r+   z
admin.E027zyThe value of '%s' refers to '%s', which must not be a DateTimeField, a ForeignKey, a OneToOneField, or a ManyToManyField.z
admin.E028N)rS   rT   rU   r	   rV   r2   r
   DateTimeFieldrX   rr   r   r0   r_   )rC   rG   rK   ra   rR   r   r   r   r     s    $!	
z3BaseModelAdminChecks._check_prepopulated_fields_keyc                sg   t  | t t f  s1 t d d   d  d d St t j     f d d   t |  D   Sd S)	zf Check a value of `prepopulated_fields` dictionary, i.e. it's an
        iterable of existing fields. za list or tuplerE   rG   r+   z
admin.E029c             3   s4   |  ]* \ } }  j   | d    | f  Vq d S)z%s[%r]N)%_check_prepopulated_fields_value_item)rI   rJ   Zsubfield_name)ra   rG   rC   r   r   rd     s   zHBaseModelAdminChecks._check_prepopulated_fields_value.<locals>.<genexpr>N)r2   rM   rN   rO   r   rP   rQ   )rC   rG   r}   ra   r   )ra   rG   rC   r   r     s
    	z5BaseModelAdminChecks._check_prepopulated_fields_valuec             C   sS   y | j  j j |  Wn1 t k
 rJ t d | d | d | d d  SYn Xg  Sd S)z[ For `prepopulated_fields` equal to {"slug": ("title",)},
        `field_name` is "title". rR   rE   rG   r+   z
admin.E030N)rS   rT   rU   r	   rV   )rC   rG   rK   ra   r   r   r   r   	  s
    $z:BaseModelAdminChecks._check_prepopulated_fields_value_itemc                s}     j  d k r g  St   j  t t f  sG t d d d d   d d St t j    f d d	   t   j   D   Sd S)
z= Check that ordering refers to existing fields or is random. Nza list or tuplerE   orderingrG   r+   z
admin.E031c             3   s.   |  ]$ \ } }  j    | d  |  Vq d S)zordering[%d]N)_check_ordering_item)rI   rJ   rK   )rG   rC   r   r   rd     s   z7BaseModelAdminChecks._check_ordering.<locals>.<genexpr>)r   r2   rM   rN   rO   r   rP   rQ   )rC   rG   r   )rG   rC   r   rA     s    	z$BaseModelAdminChecks._check_orderingc             C   s=  t  | t t f  rU t  | t  s0 | j   } t  | j t  rQ | j j } n g  S| d k r t | j  d k r t	 j
 d d d d | j d d g S| d k r g  St | k r g  S| j d	  r | d d
  } | d k r g  Sy | j j j |  Wn1 t k
 r4t d | d | d | d d  SYn Xg  Sd
 S)z2 Check that `ordering` refers to existing fields. ?rn   z^The value of 'ordering' has the random ordering marker '?', but contains other fields as well.Zhintz2Either remove the "?", or remove the other fields.rG   r+   z
admin.E032-NpkrR   rE   z
admin.E033)r2   r   r   ZascZ
expressionr   namerh   r   r   r0   r_   r   
startswithrS   rT   rU   r	   rV   )rC   rG   rK   ra   r   r   r   r   "  s2    !	
$z)BaseModelAdminChecks._check_ordering_itemc                s}     j  f  k r g  St   j  t t f  sG t d d d d   d d St t j    f d d   t   j   D   Sd	 S)
zA Check that readonly_fields refers to proper attribute or field. za list or tuplerE   rq   rG   r+   z
admin.E034c             3   s.   |  ]$ \ } }  j    | d  |  Vq d S)zreadonly_fields[%d]N)_check_readonly_fields_item)rI   rJ   rK   )rG   rC   r   r   rd   P  s   z>BaseModelAdminChecks._check_readonly_fields.<locals>.<genexpr>N)rq   r2   rM   rN   rO   r   rP   rQ   )rC   rG   r   )rG   rC   r   rB   G  s    	z+BaseModelAdminChecks._check_readonly_fieldsc             C   s   t  |  r g  St | |  r# g  St | j |  r9 g  Sy | j j j |  WnY t k
 r t j d | | j j	 | j j j
 | j j j f d | j d d g SYn Xg  Sd  S)NzVThe value of '%s' is not a callable, an attribute of '%s', or an attribute of '%s.%s'.rG   r+   z
admin.E035)r   hasattrrS   rT   rU   r	   r   r0   r_   r]   	app_labelobject_name)rC   rG   rK   ra   r   r   r   r   T  s    +	z0BaseModelAdminChecks._check_readonly_fields_itemN)r]   
__module____qualname__r    r6   rH   r7   rc   r8   r9   rj   rf   rp   r:   r;   r<   r=   rx   r>   r{   r|   r@   r?   r   r   r   rA   r   rB   r   r   r   r   r   r5      s6   + #

%r5   c                   s  e  Z d  Z   f 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 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% d&   Z d' d(   Z   S))ModelAdminChecksc                s   t    j |  |  j |  |  j |  |  j |  |  j |  |  j |  |  j |  |  j |  |  j	 |  |  j
 |  |  j |  |  j |  |  j |  |  j |  |  j |   S)N)superr    _check_save_as_check_save_on_top_check_inlines_check_list_display_check_list_display_links_check_list_filter_check_list_select_related_check_list_per_page_check_list_max_show_all_check_list_editable_check_search_fields_check_date_hierarchy _check_action_permission_methods_check_actions_uniqueness)rC   rD   r!   )r_   r   r   r    n  s    zModelAdminChecks.checkc             C   s6   t  | j t  s. t d d d d | d d Sg  Sd S)z Check save_as is a boolean. z	a booleanrE   save_asrG   r+   z
admin.E101N)r2   r   r   rO   )rC   rG   r   r   r   r     s    zModelAdminChecks._check_save_asc             C   s6   t  | j t  s. t d d d d | d d Sg  Sd S)z! Check save_on_top is a boolean. z	a booleanrE   save_on_toprG   r+   z
admin.E102N)r2   r   r   rO   )rC   rG   r   r   r   r     s    z#ModelAdminChecks._check_save_on_topc                sj   t    j t t f  s4 t d d d d   d d St t j    f d d   t   j  D   Sd	 S)
z' Check all inline model admin classes. za list or tuplerE   inlinesrG   r+   z
admin.E103c             3   s.   |  ]$ \ } }  j    | d  |  Vq d S)zinlines[%d]N)_check_inlines_item)rI   rJ   item)rG   rC   r   r   rd     s   z2ModelAdminChecks._check_inlines.<locals>.<genexpr>N)r2   r   rM   rN   rO   r   rP   rQ   )rC   rG   r   )rG   rC   r   r     s
    	zModelAdminChecks._check_inlinesc             C   s  y | j  d | j } Wn5 t k
 rO t j d | d | j d d g SYn Xd d l m } t | |  s t j d | d | j d d g S| j	 s t j d | d | j d d	 g St | j	 t
 j  s t d
 d d | d | d d S| | j	 | j  j   Sd S)z Check one inline model admin. .z*'%s' must inherit from 'InlineModelAdmin'.rG   r+   z
admin.E104r   )InlineModelAdminz#'%s' must have a 'model' attribute.z
admin.E105za ModelrE   z%s.modelz
admin.E106N)r   r]   AttributeErrorr   r0   r_   r   r   r   rS   r
   ZModelrO   rY   r    )rC   rG   inlinera   Zinline_labelr   r   r   r   r     s*    
	
	
	
	
 z$ModelAdminChecks._check_inlines_itemc                sj   t    j t t f  s4 t d d d d   d d St t j    f d d   t   j  D   Sd	 S)
zL Check that list_display only contains fields or usable attributes.
        za list or tuplerE   list_displayrG   r+   z
admin.E107c             3   s.   |  ]$ \ } }  j    | d  |  Vq d S)zlist_display[%d]N)_check_list_display_item)rI   rJ   r   )rG   rC   r   r   rd     s   z7ModelAdminChecks._check_list_display.<locals>.<genexpr>N)r2   r   rM   rN   rO   r   rP   rQ   )rC   rG   r   )rG   rC   r   r     s
    	z$ModelAdminChecks._check_list_displayc             C   s   t  |  r g  St | |  r# g  Sy | j j j |  } Wn t k
 r y t | j |  } Wn\ t k
 r t j	 d | | | j
 j | j j j | j j j f d | j
 d d g SYn XYn Xt | t j  r t j	 d | d | j
 d d g Sg  S)NzvThe value of '%s' refers to '%s', which is not a callable, an attribute of '%s', or an attribute or method on '%s.%s'.rG   r+   z
admin.E108z0The value of '%s' must not be a ManyToManyField.z
admin.E109)r   r   rS   rT   rU   r	   getattrr   r   r0   r_   r]   r   r   r2   r
   rr   )rC   rG   r   ra   rR   r   r   r   r     s,    	
	
z)ModelAdminChecks._check_list_display_itemc                s   d d l  m }   j d k r# g  St   j t t f  sW t d d d d   d d	 S  j j | j k r t t	 j
    f d
 d   t   j  D   Sg  S)zK Check that list_display_links is a unique subset of list_display.
        r   )
ModelAdminNza list, a tuple, or NonerE   list_display_linksrG   r+   z
admin.E110c             3   s.   |  ]$ \ } }  j    | d  |  Vq d S)zlist_display_links[%d]N)_check_list_display_links_item)rI   rJ   rK   )rG   rC   r   r   rd     s   z=ModelAdminChecks._check_list_display_links.<locals>.<genexpr>)r   r   r   r2   rM   rN   rO   Zget_list_display__func__r   rP   rQ   )rC   rG   r   r   )rG   rC   r   r     s    	z*ModelAdminChecks._check_list_display_linksc             C   s@   | | j  k r8 t j d | | f d | j d d g Sg  Sd  S)NzIThe value of '%s' refers to '%s', which is not defined in 'list_display'.rG   r+   z
admin.E111)r   r   r0   r_   )rC   rG   rK   ra   r   r   r   r      s    	
z/ModelAdminChecks._check_list_display_links_itemc                sj   t    j t t f  s4 t d d d d   d d St t j    f d d   t   j  D   Sd  S)	Nza list or tuplerE   list_filterrG   r+   z
admin.E112c             3   s.   |  ]$ \ } }  j    | d  |  Vq d S)zlist_filter[%d]N)_check_list_filter_item)rI   rJ   r   )rG   rC   r   r   rd     s   z6ModelAdminChecks._check_list_filter.<locals>.<genexpr>)r2   r   rM   rN   rO   r   rP   rQ   )rC   rG   r   )rG   rC   r   r     s
    	z#ModelAdminChecks._check_list_filterc             C   s\  d d l  m } m } t |  r t | t j  r t | |  sc t d d d | d | d d  St	 | |  r t
 j d	 | d | j d d
 g Sg  Sn t | t t f  r | \ } } t | |  s t d d d d | d | d d  Sg  Snb | } y t | j |  WnA t t f k
 rSt
 j d | | f d | j d d g SYn Xg  Sd S)aG  
        Check one item of `list_filter`, i.e. check if it is one of three options:
        1. 'field' -- a basic field filter, possibly w/ relationships (e.g.
           'field__rel')
        2. ('field', SomeFieldListFilter) - a field-based list filter class
        3. SomeListFilter - a non-field list filter class
        r   )
ListFilterFieldListFilterrt   r   rE   rG   r+   z
admin.E113z:The value of '%s' must not inherit from 'FieldListFilter'.z
admin.E114r   z%s[1]z
admin.E115zBThe value of '%s' refers to '%s', which does not refer to a Field.z
admin.E116N)Zdjango.contrib.adminr   r   r   r2   r
   ZFieldr   rv   r   r   r0   r_   rN   rM   r   rS   r   r	   )rC   rG   r   ra   r   r   rR   Zlist_filter_classr   r   r   r     s2    	
	
#	z(ModelAdminChecks._check_list_filter_itemc             C   s?   t  | j t t t f  s7 t d d d d | d d Sg  Sd S)zA Check that list_select_related is a boolean, a list or a tuple. za boolean, tuple or listrE   list_select_relatedrG   r+   z
admin.E117N)r2   r   r   rM   rN   rO   )rC   rG   r   r   r   r   K  s    z+ModelAdminChecks._check_list_select_relatedc             C   s6   t  | j t  s. t d d d d | d d Sg  Sd S)z) Check that list_per_page is an integer. z
an integerrE   list_per_pagerG   r+   z
admin.E118N)r2   r   intrO   )rC   rG   r   r   r   r   S  s    z%ModelAdminChecks._check_list_per_pagec             C   s6   t  | j t  s. t d d d d | d d Sg  Sd S)z- Check that list_max_show_all is an integer. z
an integerrE   list_max_show_allrG   r+   z
admin.E119N)r2   r   r   rO   )rC   rG   r   r   r   r   [  s    z)ModelAdminChecks._check_list_max_show_allc                sj   t    j t t f  s4 t d d d d   d d St t j    f d d   t   j  D   Sd	 S)
zl Check that list_editable is a sequence of editable fields from
        list_display without first element. za list or tuplerE   list_editablerG   r+   z
admin.E120c             3   s.   |  ]$ \ } }  j    | d  |  Vq d S)zlist_editable[%d]N)_check_list_editable_item)rI   rJ   r   )rG   rC   r   r   rd   k  s   z8ModelAdminChecks._check_list_editable.<locals>.<genexpr>N)r2   r   rM   rN   rO   r   rP   rQ   )rC   rG   r   )rG   rC   r   r   c  s
    	z%ModelAdminChecks._check_list_editablec             C   sV  y | j  j j |  } Wn1 t k
 rL t d | d | d | d d  SYnX| | j k r t j d | | f d | j d d g S| j	 r | | j	 k r t j d | d | j d d	 g S| j d
 | k r| j	 r| j	 d  k	 rt j d | | j d
 f d | j d d g S| j
 sNt j d | | f d | j d d g Sg  Sd  S)NrR   rE   rG   r+   z
admin.E121zKThe value of '%s' refers to '%s', which is not contained in 'list_display'.z
admin.E122zMThe value of '%s' cannot be in both 'list_editable' and 'list_display_links'.z
admin.E123r   z~The value of '%s' refers to the first field in 'list_display' ('%s'), which cannot be used unless 'list_display_links' is set.z
admin.E124zJThe value of '%s' refers to '%s', which is not editable through the admin.z
admin.E125)rS   rT   rU   r	   rV   r   r   r0   r_   r   editable)rC   rG   rK   ra   rR   r   r   r   r   o  s:    $	

	
	
		
z*ModelAdminChecks._check_list_editable_itemc             C   s<   t  | j t t f  s4 t d d d d | d d Sg  Sd S)z$ Check search_fields is a sequence. za list or tuplerE   r`   rG   r+   z
admin.E126N)r2   r`   rM   rN   rO   )rC   rG   r   r   r   r     s    z%ModelAdminChecks._check_search_fieldsc             C   s   | j  d k r g  Sy t | j | j   d } Wn> t t f k
 rp t j d | j  d | j d d g SYn< Xt | t	 j
 t	 j f  s t d d d	 d | d d
 Sg  Sd S)zA Check that date_hierarchy refers to DateField or DateTimeField. Nrn   zNThe value of 'date_hierarchy' refers to '%s', which does not refer to a Field.rG   r+   z
admin.E127za DateField or DateTimeFieldrE   date_hierarchyz
admin.E128)r   r   rS   r   r	   r   r0   r_   r2   r
   Z	DateFieldr   rO   )rC   rG   rR   r   r   r   r     s    
	z&ModelAdminChecks._check_date_hierarchyc       	   	   C   s   | j    } g  } x | D] \ } } } t | d  s: q xe | j D]Z } d | } t | |  sD | j t j d | j j | | j f d | j d d  qD Wq W| S)z
        Actions with an allowed_permission attribute require the ModelAdmin to
        implement a has_<perm>_permission() method for each permission.
        allowed_permissionszhas_%s_permissionz/%s must define a %s() method for the %s action.rG   r+   z
admin.E129)_get_base_actionsr   r   r/   r   r0   r_   r]   )	rC   rG   Zactionsr"   funcr   _Z
permissionmethod_namer   r   r   r     s"    
		z1ModelAdminChecks._check_action_permission_methodsc             C   sa   d d   | j    D } t |  t t |   k r] t j d | j d | j d d g Sg  S)z.Check that every action has a unique __name__.c             S   s   g  |  ] \ } } } |  q Sr   r   )rI   r   r   r   r   r   rL     s   	 z>ModelAdminChecks._check_actions_uniqueness.<locals>.<listcomp>z<__name__ attributes of actions defined in %s must be unique.rG   r+   z
admin.E130)r   rh   ri   r   r0   r_   )rC   rG   namesr   r   r   r     s    
	
z*ModelAdminChecks._check_actions_uniqueness)r]   r   r   r    r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )r_   r   r   l  s(   		$!	42r   c                   sp   e  Z d  Z   f d d   Z   f d d   Z d d   Z d d   Z d	 d
   Z d d   Z d d   Z	   S)InlineModelAdminChecksc                sj   | j  } t   j |  |  j | |  |  j | |  |  j |  |  j |  |  j |  |  j |   S)N)	parent_modelr   r    _check_relation_check_exclude_of_parent_model_check_extra_check_max_num_check_min_num_check_formset)rC   Z
inline_objr!   r   )r_   r   r   r      s    	zInlineModelAdminChecks.checkc                s   t    j |  } | r g  S|  j | |  r2 g  S| j d  k rE g  St | | j d | j } | j | j k r t j	 d | j | j
 j | j
 j f d | j d d g Sg  Sd  S)Nfk_namezYCannot exclude the field '%s', because it is the foreign key to the parent model '%s.%s'.rG   r+   z
admin.E201)r   r:   r   rs   r   rS   r   r   r   r0   rT   r   r   r_   )rC   rG   r   r"   Zfk)r_   r   r   r     s    	
z5InlineModelAdminChecks._check_exclude_of_parent_modelc             C   ss   y t  | | j d | j WnK t k
 rj } z+ t j | j d d | j d d g SWYd  d  } ~ Xn Xg  Sd  S)Nr   r   rG   r+   z
admin.E202)r   rS   r   
ValueErrorr   r0   argsr_   )rC   rG   r   er   r   r   r     s
    9z&InlineModelAdminChecks._check_relationc             C   s6   t  | j t  s. t d d d d | d d Sg  Sd S)z! Check that extra is an integer. z
an integerrE   extrarG   r+   z
admin.E203N)r2   r   r   rO   )rC   rG   r   r   r   r     s    z#InlineModelAdminChecks._check_extrac             C   sI   | j  d k r g  St | j  t  sA t d d d d | d d Sg  Sd S)z# Check that max_num is an integer. Nz
an integerrE   max_numrG   r+   z
admin.E204)r   r2   r   rO   )rC   rG   r   r   r   r   "  s
    z%InlineModelAdminChecks._check_max_numc             C   sI   | j  d k r g  St | j  t  sA t d d d d | d d Sg  Sd S)z# Check that min_num is an integer. Nz
an integerrE   min_numrG   r+   z
admin.E205)r   r2   r   rO   )rC   rG   r   r   r   r   ,  s
    z%InlineModelAdminChecks._check_min_numc          	   C   s9   t  | j t  s1 t d d d d d | d d  Sg  Sd S)	z2 Check formset is a subclass of BaseModelFormSet. rt   r   rE   formsetrG   r+   z
admin.E206N)r   r   r   rv   )rC   rG   r   r   r   r   6  s    z%InlineModelAdminChecks._check_formset)
r]   r   r   r    r   r   r   r   r   r   r   r   )r_   r   r     s   

r   c             C   s)   t  j d | |  f d | j d | g S)NzThe value of '%s' must be %s.rG   r+   )r   r0   r_   )r^   rE   rG   r+   r   r   r   rO   ?  s    	rO   c             C   s)   t  j d | |  f d | j d | g S)Nz)The value of '%s' must inherit from '%s'.rG   r+   )r   r0   r_   )rt   rE   rG   r+   r   r   r   rv   I  s    	rv   c             C   sA   t  j d | |  | j j j | j j j f d | j d | g S)NzGThe value of '%s' refers to '%s', which is not an attribute of '%s.%s'.rG   r+   )r   r0   rS   rT   r   r   r_   )rR   rE   rG   r+   r   r   r   rV   S  s
    %	rV   N)*	itertoolsr   Zdjango.appsr   Zdjango.confr   Zdjango.contrib.admin.utilsr   r   r   Zdjango.corer   Zdjango.core.exceptionsr	   Z	django.dbr
   Zdjango.db.models.constantsr   Zdjango.db.models.expressionsr   r   r   Zdjango.forms.modelsr   r   r   Zdjango.templater   Zdjango.template.backends.djangor   Zdjango.utils.module_loadingr   r   r   r$   r4   r5   r   r   rO   rv   rV   r   r   r   r   <module>   s0   H  |X

