3
7^c                 @   s>  d dl 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 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l!m"Z" d dl#m$Z$ dd Z%dd Z&dd Z'dd Z(G dd dZ)G dd de)Z*G dd de)Z+dd  Z,d!d" Z-d#d$ Z.dS )%    N)chain)apps)settings)NotRelationFieldflattenget_fields_from_path)checks)FieldDoesNotExist)models)
LOOKUP_SEP)
CombinableFOrderBy)BaseModelFormBaseModelFormSet_get_foreign_key)engines)DjangoTemplates)RemovedInDjango30Warning)get_func_args)import_stringc             C   s$   y
t | |S  tk
r   dS X d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-8app2_gc/Django/django/contrib/admin/checks.py_issubclass   s    
r   c             C   sL   t | }x>|D ]6}yt |}W n tk
r4   wY nX t||rdS qW d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   s2   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_app4   s
    
r&   c              K   sB  t jdsg S g }d!}x6|D ].\}}t j|s|jtjd| d	| d
 qW x&tj D ]}t|trX|j	}P qXW d}|s|jtjddd
 nHd|j
krtdtjr|jtjddd
 d|j
kr|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
 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.z	admin.E%d)idNzA '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/   r0   )r   Zis_installedappendr   Errorr   all
isinstancer   engineZcontext_processorsr   r   ZAUTHENTICATION_BACKENDSZ
MIDDLEWARE)r#   r$   Zapp_dependenciesZapp_nameZ
error_coder5   Zdjango_templates_instancer   r   r   check_dependencies<   sZ    
  






r6   c               @   s   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d1d2 Zd3d4 Zd5d6 Zd7S )8BaseModelAdminChecksc             K   sl   | 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                sH   t  jttfs tdd ddS ttj fddt jD S dS )zV
        Check that `autocomplete_fields` is a list or tuple of model fields.
        za list or tupleautocomplete_fieldsz
admin.E036)optionobjr-   c                s"   g | ]\}}j  |d | qS )zautocomplete_fields[%d])_check_autocomplete_fields_item).0index
field_name)rI   rE   r   r   
<listcomp>   s   zCBaseModelAdminChecks._check_autocomplete_fields.<locals>.<listcomp>N)r4   rG   listtuplemust_ber   from_iterable	enumerate)rE   rI   r   )rI   rE   r   r8      s
    z/BaseModelAdminChecks._check_autocomplete_fieldsc             C   s   y|j jj|}W n  tk
r2   t|||ddS X |j rZt|tj rZt	d||ddS |j
jj|jj }|dkrtjd|jj jt|jf |jdd	gS |jstjd
|jjt|jf |jdd	gS g S d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.
        z
admin.E037)fieldrH   rI   r-   z%a foreign key or a many-to-many fieldz
admin.E038)rH   rI   r-   NzXAn admin for model "%s" has to be registered to be referenced by %s.autocomplete_fields.z
admin.E039)rI   r-   zR%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_manyr4   r
   
ForeignKeyrQ   
admin_site	_registrygetremote_fieldr   r2   __name__type	__class__search_fields)rE   rI   rM   labelrT   Zrelated_adminr   r   r   rJ      s0    

z4BaseModelAdminChecks._check_autocomplete_fields_itemc                sH   t  jttfs tdd ddS ttj fddt jD S dS )z\ Check that `raw_id_fields` only contains field names that are listed
        on the model. za list or tupleraw_id_fieldsz
admin.E001)rH   rI   r-   c             3   s$   | ]\}}j  |d | V  qdS )zraw_id_fields[%d]N)_check_raw_id_fields_item)rK   rL   rM   )rI   rE   r   r   	<genexpr>   s   z<BaseModelAdminChecks._check_raw_id_fields.<locals>.<genexpr>N)r4   rd   rO   rP   rQ   r   rR   rS   )rE   rI   r   )rI   rE   r   r9      s
    z)BaseModelAdminChecks._check_raw_id_fieldsc             C   sb   y|j jj|}W n  tk
r2   t|||ddS X |j rZt|tj rZt	d||ddS g S d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. z
admin.E002)rT   rH   rI   r-   z%a foreign key or a many-to-many fieldz
admin.E003)rH   rI   r-   N)
rU   rV   rW   r	   rX   rY   r4   r
   rZ   rQ   )rE   rI   rM   rc   rT   r   r   r   re      s    z.BaseModelAdminChecks._check_raw_id_fields_itemc                s    j dkrg S t j ttfs.tdd ddS  jrHtjd jddgS t	 j }t
|t
t|krztjd	 jd
dgS t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 tuplefieldsz
admin.E004)rH   rI   r-   z,Both 'fieldsets' and 'fields' are specified.z
admin.E005)rI   r-   z2The value of 'fields' contains duplicate field(s).z
admin.E006c             3   s   | ]}j  |d V  qdS )rg   N)_check_field_spec)rK   rM   )rI   rE   r   r   rf     s   z5BaseModelAdminChecks._check_fields.<locals>.<genexpr>)rg   r4   rO   rP   rQ   	fieldsetsr   r2   ra   r   lensetr   rR   )rE   rI   rg   r   )rI   rE   r   r:      s$    



z"BaseModelAdminChecks._check_fieldsc                s\    j dkrg S t j ttfs.tdd ddS g ttj fddt j D S dS )zT Check that fieldsets is properly formatted and doesn't contain
        duplicates. Nza list or tupleri   z
admin.E007)rH   rI   r-   c             3   s&   | ]\}}j  |d | V  qdS )zfieldsets[%d]N)_check_fieldsets_item)rK   rL   fieldset)rI   seen_fieldsrE   r   r   rf     s   z8BaseModelAdminChecks._check_fieldsets.<locals>.<genexpr>)ri   r4   rO   rP   rQ   r   rR   rS   )rE   rI   r   )rI   rn   rE   r   r;   	  s    
z%BaseModelAdminChecks._check_fieldsetsc                s  t |ttfstd ddS t|dkr:td ddS t |d ts\tdd	  d
dS d|d krtjd  jddgS t |d d ttfstdd  ddS |j	t
|d d  t|tt|krtjd  jddgS t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 tuplez
admin.E008)rH   rI   r-      zof length 2z
admin.E009   za dictionaryz%s[1]z
admin.E010rg   z3The value of '%s[1]' must contain the key 'fields'.z
admin.E011)rI   r-   z%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)rh   )rK   Zfieldset_fields)rc   rI   rE   r   r   rf   7  s   z=BaseModelAdminChecks._check_fieldsets_item.<locals>.<genexpr>)r4   rO   rP   rQ   rj   dictr   r2   ra   r!   r   rk   r   rR   )rE   rI   rm   rc   rn   r   )rc   rI   rE   r   rl     s,    

z*BaseModelAdminChecks._check_fieldsets_itemc                s@   t |tr.ttj fddt|D S j| S d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   s(   | ] \}}j |d  |f V  qdS )z%s[%d]N)_check_field_spec_item)rK   rL   rM   )rc   rI   rE   r   r   rf   B  s   z9BaseModelAdminChecks._check_field_spec.<locals>.<genexpr>N)r4   rP   rO   r   rR   rS   rr   )rE   rI   rg   rc   r   )rc   rI   rE   r   rh   ;  s
    
z&BaseModelAdminChecks._check_field_specc             C   st   ||j krg S y|jjj|}W n tk
r4   g S X t|tjrl|jj	jj
 rltjd||f |jddgS g S d S )NzvThe value of '%s' cannot include the ManyToManyField '%s', because that field manually specifies a relationship model.z
admin.E013)rI   r-   )readonly_fieldsrU   rV   rW   r	   r4   r
   ManyToManyFieldr^   ZthroughZauto_createdr   r2   ra   )rE   rI   rM   rc   rT   r   r   r   rr   H  s    

z+BaseModelAdminChecks._check_field_spec_itemc             C   sb   |j dkrg S t|j ttfs.tdd|ddS t|j tt|j krZtjd|j	ddgS g S dS )	z6 Check that exclude is a sequence without duplicates. Nza list or tupleexcludez
admin.E014)rH   rI   r-   z3The value of 'exclude' contains duplicate field(s).z
admin.E015)rI   r-   )
ru   r4   rO   rP   rQ   rj   rk   r   r2   ra   )rE   rI   r   r   r   r<   d  s    

z#BaseModelAdminChecks._check_excludec             C   s$   t |jtstdd|ddS g S dS )z+ Check that form subclasses BaseModelForm. r   formz
admin.E016)parentrH   rI   r-   N)r   rv   r   must_inherit_from)rE   rI   r   r   r   r=   v  s    
z BaseModelAdminChecks._check_formc                sH   t  jttfs tdd ddS ttj fddt jD S dS )z: Check that filter_vertical is a sequence of field names. za list or tuplefilter_verticalz
admin.E017)rH   rI   r-   c             3   s$   | ]\}}j  |d | V  qdS )zfilter_vertical[%d]N)_check_filter_item)rK   rL   rM   )rI   rE   r   r   rf     s   z>BaseModelAdminChecks._check_filter_vertical.<locals>.<genexpr>N)r4   ry   rO   rP   rQ   r   rR   rS   )rE   rI   r   )rI   rE   r   r>   ~  s
    z+BaseModelAdminChecks._check_filter_verticalc                sH   t  jttfs tdd ddS ttj fddt jD S dS )z< Check that filter_horizontal is a sequence of field names. za list or tuplefilter_horizontalz
admin.E018)rH   rI   r-   c             3   s$   | ]\}}j  |d | V  qdS )zfilter_horizontal[%d]N)rz   )rK   rL   rM   )rI   rE   r   r   rf     s   z@BaseModelAdminChecks._check_filter_horizontal.<locals>.<genexpr>N)r4   r{   rO   rP   rQ   r   rR   rS   )rE   rI   r   )rI   rE   r   r?     s
    z-BaseModelAdminChecks._check_filter_horizontalc             C   sR   y|j jj|}W n  tk
r2   t|||ddS X |jsJtd||ddS g S dS )z Check one item of `filter_vertical` or `filter_horizontal`, i.e.
        check that given field exists and is a ManyToManyField. z
admin.E019)rT   rH   rI   r-   za many-to-many fieldz
admin.E020)rH   rI   r-   N)rU   rV   rW   r	   rX   rY   rQ   )rE   rI   rM   rc   rT   r   r   r   rz     s    z'BaseModelAdminChecks._check_filter_itemc                sD   t  jtstdd ddS ttj fdd jj D S dS )z, Check that `radio_fields` is a dictionary. za dictionaryradio_fieldsz
admin.E021)rH   rI   r-   c             3   s2   | ]*\}}j  |d j |d|  V  qdS )r|   zradio_fields["%s"]N)_check_radio_fields_key_check_radio_fields_value)rK   rM   val)rI   rE   r   r   rf     s   z;BaseModelAdminChecks._check_radio_fields.<locals>.<genexpr>N)r4   r|   rq   rQ   rO   r   rR   items)rE   rI   r   )rI   rE   r   r@     s
    z(BaseModelAdminChecks._check_radio_fieldsc             C   sj   y|j jj|}W n  tk
r2   t|||ddS X t|tjpD|jsbt	j
d||f |jddgS g S d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. z
admin.E022)rT   rH   rI   r-   zsThe value of '%s' refers to '%s', which is not an instance of ForeignKey, and does not have a 'choices' definition.z
admin.E023)rI   r-   N)rU   rV   rW   r	   rX   r4   r
   rZ   choicesr   r2   ra   )rE   rI   rM   rc   rT   r   r   r   r}     s    
z,BaseModelAdminChecks._check_radio_fields_keyc             C   s<   ddl m}m} |||fkr4tjd| |jddgS g S d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.z
admin.E024)rI   r-   N)django.contrib.admin.optionsr   r   r   r2   ra   )rE   rI   r   rc   r   r   r   r   r   r~     s    
z.BaseModelAdminChecks._check_radio_fields_valuec             C   s6   t |j r.t|jt r.tjd|jddgS g S d S )NzBThe value of 'view_on_site' must be a callable or a boolean value.z
admin.E025)rI   r-   )callableZview_on_siter4   boolr   r2   ra   )rE   rI   r   r   r   rB     s    
z,BaseModelAdminChecks._check_view_on_site_urlc                sD   t  jtstdd ddS ttj fdd jj D S dS )zZ Check that `prepopulated_fields` is a dictionary containing allowed
        field types. za dictionaryprepopulated_fieldsz
admin.E026)rH   rI   r-   c             3   s2   | ]*\}}j  |d j |d|  V  qdS )r   zprepopulated_fields["%s"]N)_check_prepopulated_fields_key _check_prepopulated_fields_value)rK   rM   r   )rI   rE   r   r   rf     s   zBBaseModelAdminChecks._check_prepopulated_fields.<locals>.<genexpr>N)r4   r   rq   rQ   rO   r   rR   r   )rE   rI   r   )rI   rE   r   rA     s
    z/BaseModelAdminChecks._check_prepopulated_fieldsc             C   sn   y|j jj|}W n  tk
r2   t|||ddS X t|tjtjtj	frft
jd||f |jddgS g S d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.
        z
admin.E027)rT   rH   rI   r-   zyThe value of '%s' refers to '%s', which must not be a DateTimeField, a ForeignKey, a OneToOneField, or a ManyToManyField.z
admin.E028)rI   r-   N)rU   rV   rW   r	   rX   r4   r
   DateTimeFieldrZ   rt   r   r2   ra   )rE   rI   rM   rc   rT   r   r   r   r     s    
z3BaseModelAdminChecks._check_prepopulated_fields_keyc                sF   t |ttfstd ddS ttj fddt|D S dS )zf Check a value of `prepopulated_fields` dictionary, i.e. it's an
        iterable of existing fields. za list or tuplez
admin.E029)rH   rI   r-   c             3   s(   | ] \}}j |d  |f V  qdS )z%s[%r]N)%_check_prepopulated_fields_value_item)rK   rL   Zsubfield_name)rc   rI   rE   r   r   rf     s   zHBaseModelAdminChecks._check_prepopulated_fields_value.<locals>.<genexpr>N)r4   rO   rP   rQ   r   rR   rS   )rE   rI   r   rc   r   )rc   rI   rE   r   r      s
    z5BaseModelAdminChecks._check_prepopulated_fields_valuec             C   s<   y|j jj| W n  tk
r2   t|||ddS X g S dS )z[ For `prepopulated_fields` equal to {"slug": ("title",)},
        `field_name` is "title". z
admin.E030)rT   rH   rI   r-   N)rU   rV   rW   r	   rX   )rE   rI   rM   rc   r   r   r   r     s
    z:BaseModelAdminChecks._check_prepopulated_fields_value_itemc                sV    j dkrg S t j ttfs.tdd ddS ttj fddt j D S dS )z= Check that ordering refers to existing fields or is random. Nza list or tupleorderingz
admin.E031)rH   rI   r-   c             3   s$   | ]\}}j  |d | V  qdS )zordering[%d]N)_check_ordering_item)rK   rL   rM   )rI   rE   r   r   rf   !  s   z7BaseModelAdminChecks._check_ordering.<locals>.<genexpr>)r   r4   rO   rP   rQ   r   rR   rS   )rE   rI   r   )rI   rE   r   rC     s    
z$BaseModelAdminChecks._check_orderingc             C   s   t |ttfr:t |ts |j }t |jtr6|jj}ng S |dkrft|jdkrft	j
dd|jddgS |dkrrg S t|kr~g S |jdr|dd }|d	krg S y|jjj| W n  tk
r   t|||d
dS X g S dS )z2 Check that `ordering` refers to existing fields. ?rp   z^The value of 'ordering' has the random ordering marker '?', but contains other fields as well.z2Either remove the "?", or remove the other fields.z
admin.E032)ZhintrI   r-   -Npkz
admin.E033)rT   rH   rI   r-   )r4   r   r   ZascZ
expressionr   namerj   r   r   r2   ra   r   
startswithrU   rV   rW   r	   rX   )rE   rI   rM   rc   r   r   r   r   %  s2    



z)BaseModelAdminChecks._check_ordering_itemc                sV    j f krg S t j ttfs.tdd ddS ttj fddt j D S dS )zA Check that readonly_fields refers to proper attribute or field. za list or tuplers   z
admin.E034)rH   rI   r-   c             3   s$   | ]\}}j  |d | V  qdS )zreadonly_fields[%d]N)_check_readonly_fields_item)rK   rL   rM   )rI   rE   r   r   rf   S  s   z>BaseModelAdminChecks._check_readonly_fields.<locals>.<genexpr>N)rs   r4   rO   rP   rQ   r   rR   rS   )rE   rI   r   )rI   rE   r   rD   J  s    
z+BaseModelAdminChecks._check_readonly_fieldsc             C   s   t |rg S t||rg S t|j|r*g S y|jjj| W n@ tk
r|   tjd||jj	|jjj
|jjjf |jddgS X g S d S )NzVThe value of '%s' is not a callable, an attribute of '%s', or an attribute of '%s.%s'.z
admin.E035)rI   r-   )r   hasattrrU   rV   rW   r	   r   r2   ra   r_   	app_labelobject_name)rE   rI   rM   rc   r   r   r   r   W  s    
z0BaseModelAdminChecks._check_readonly_fields_itemN)r_   
__module____qualname__r"   r8   rJ   r9   re   r:   r;   rl   rh   rr   r<   r=   r>   r?   rz   r@   r}   r~   rB   rA   r   r   r   rC   r   rD   r   r   r   r   r   r7      s6   + #

%r7   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  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)rE   rF   r#   )ra   r   r   r"   q  s    
zModelAdminChecks.checkc             C   s$   t |jtstdd|ddS g S dS )z Check save_as is a boolean. z	a booleansave_asz
admin.E101)rH   rI   r-   N)r4   r   r   rQ   )rE   rI   r   r   r   r     s    
zModelAdminChecks._check_save_asc             C   s$   t |jtstdd|ddS g S dS )z! Check save_on_top is a boolean. z	a booleansave_on_topz
admin.E102)rH   rI   r-   N)r4   r   r   rQ   )rE   rI   r   r   r   r     s    
z#ModelAdminChecks._check_save_on_topc                sH   t  jttfs tdd ddS ttj fddt jD S dS )z' Check all inline model admin classes. za list or tupleinlinesz
admin.E103)rH   rI   r-   c             3   s$   | ]\}}j  |d | V  qdS )zinlines[%d]N)_check_inlines_item)rK   rL   item)rI   rE   r   r   rf     s   z2ModelAdminChecks._check_inlines.<locals>.<genexpr>N)r4   r   rO   rP   rQ   r   rR   rS   )rE   rI   r   )rI   rE   r   r     s
    zModelAdminChecks._check_inlinesc             C   s   y|j d |j }W n( tk
r<   tjd| |jddgS X ddlm} t||sltjd| |jddgS |j	stjd| |jddgS t|j	t
jstd	d
| |ddS ||j	|jj S dS )z Check one inline model admin. .z*'%s' must inherit from 'InlineModelAdmin'.z
admin.E104)rI   r-   r   )InlineModelAdminz#'%s' must have a 'model' attribute.z
admin.E105za Modelz%s.modelz
admin.E106)rH   rI   r-   N)r   r_   AttributeErrorr   r2   ra   r   r   r   rU   r
   ZModelrQ   r[   r"   )rE   rI   inlinerc   Zinline_labelr   r   r   r   r     s*    


z$ModelAdminChecks._check_inlines_itemc                sH   t  jttfs tdd ddS ttj fddt jD S dS )zL Check that list_display only contains fields or usable attributes.
        za list or tuplelist_displayz
admin.E107)rH   rI   r-   c             3   s$   | ]\}}j  |d | V  qdS )zlist_display[%d]N)_check_list_display_item)rK   rL   r   )rI   rE   r   r   rf     s   z7ModelAdminChecks._check_list_display.<locals>.<genexpr>N)r4   r   rO   rP   rQ   r   rR   rS   )rE   rI   r   )rI   rE   r   r     s
    z$ModelAdminChecks._check_list_displayc             C   s   t |rg S t||rg S t|j|rxy|jjj|}W n tk
rL   g S X t|tjrrt	j
d| |jddgS g S n2t	j
d|||jj|jjj|jjjf |jddgS d S )Nz0The value of '%s' must not be a ManyToManyField.z
admin.E109)rI   r-   zvThe value of '%s' refers to '%s', which is not a callable, an attribute of '%s', or an attribute or method on '%s.%s'.z
admin.E108)r   r   rU   rV   rW   r	   r4   r
   rt   r   r2   ra   r_   r   r   )rE   rI   r   rc   rT   r   r   r   r     s*    


z)ModelAdminChecks._check_list_display_itemc                sp   ddl m}  jdkrg S t jttfs:tdd ddS  jj|jkrltt	j
 fdd	t jD S g S )
zK Check that list_display_links is a unique subset of list_display.
        r   )
ModelAdminNza list, a tuple, or Nonelist_display_linksz
admin.E110)rH   rI   r-   c             3   s$   | ]\}}j  |d | V  qdS )zlist_display_links[%d]N)_check_list_display_links_item)rK   rL   rM   )rI   rE   r   r   rf     s   z=ModelAdminChecks._check_list_display_links.<locals>.<genexpr>)r   r   r   r4   rO   rP   rQ   Zget_list_display__func__r   rR   rS   )rE   rI   r   r   )rI   rE   r   r     s    
z*ModelAdminChecks._check_list_display_linksc             C   s.   ||j kr&tjd||f |jddgS g S d S )NzIThe value of '%s' refers to '%s', which is not defined in 'list_display'.z
admin.E111)rI   r-   )r   r   r2   ra   )rE   rI   rM   rc   r   r   r   r     s    

z/ModelAdminChecks._check_list_display_links_itemc                sH   t  jttfs tdd ddS ttj fddt jD S d S )Nza list or tuplelist_filterz
admin.E112)rH   rI   r-   c             3   s$   | ]\}}j  |d | V  qdS )zlist_filter[%d]N)_check_list_filter_item)rK   rL   r   )rI   rE   r   r   rf     s   z6ModelAdminChecks._check_list_filter.<locals>.<genexpr>)r4   r   rO   rP   rQ   r   rR   rS   )rE   rI   r   )rI   rE   r   r     s
    z#ModelAdminChecks._check_list_filterc             C   s   ddl m}m} t|rht|tj rht||s@td||ddS t	||rbt
jd| |jddgS g S nt|ttfr|\}}t||std	d
| |ddS g S nJ|}yt|j| W n0 ttfk
r   t
jd||f |jddgS X g S d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FieldListFilterr   z
admin.E113)rw   rH   rI   r-   z:The value of '%s' must not inherit from 'FieldListFilter'.z
admin.E114)rI   r-   r   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   r4   r
   ZFieldr   rx   r   r   r2   ra   rP   rO   r   rU   r   r	   )rE   rI   r   rc   r   r   rT   Zlist_filter_classr   r   r   r     s2    	





z(ModelAdminChecks._check_list_filter_itemc             C   s*   t |jtttfs"tdd|ddS g S dS )zA Check that list_select_related is a boolean, a list or a tuple. za boolean, tuple or listlist_select_relatedz
admin.E117)rH   rI   r-   N)r4   r   r   rO   rP   rQ   )rE   rI   r   r   r   r   N  s    z+ModelAdminChecks._check_list_select_relatedc             C   s$   t |jtstdd|ddS g S dS )z) Check that list_per_page is an integer. z
an integerlist_per_pagez
admin.E118)rH   rI   r-   N)r4   r   intrQ   )rE   rI   r   r   r   r   V  s    z%ModelAdminChecks._check_list_per_pagec             C   s$   t |jtstdd|ddS g S dS )z- Check that list_max_show_all is an integer. z
an integerlist_max_show_allz
admin.E119)rH   rI   r-   N)r4   r   r   rQ   )rE   rI   r   r   r   r   ^  s    z)ModelAdminChecks._check_list_max_show_allc                sH   t  jttfs tdd ddS ttj fddt jD S dS )zl Check that list_editable is a sequence of editable fields from
        list_display without first element. za list or tuplelist_editablez
admin.E120)rH   rI   r-   c             3   s$   | ]\}}j  |d | V  qdS )zlist_editable[%d]N)_check_list_editable_item)rK   rL   r   )rI   rE   r   r   rf   n  s   z8ModelAdminChecks._check_list_editable.<locals>.<genexpr>N)r4   r   rO   rP   rQ   r   rR   rS   )rE   rI   r   )rI   rE   r   r   f  s
    z%ModelAdminChecks._check_list_editablec             C   s   y|j jj|}W n  tk
r2   t|||ddS X ||jkrZtjd||f |jddgS |j	r||j	krtjd| |jddgS |jd |kr|j	 r|j	d k	rtjd	||jd f |jd
dgS |j
stjd||f |jddgS g S d S )Nz
admin.E121)rT   rH   rI   r-   zKThe value of '%s' refers to '%s', which is not contained in 'list_display'.z
admin.E122)rI   r-   zMThe 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)rU   rV   rW   r	   rX   r   r   r2   ra   r   editable)rE   rI   rM   rc   rT   r   r   r   r   r  s:    





z*ModelAdminChecks._check_list_editable_itemc             C   s(   t |jttfs tdd|ddS g S dS )z$ Check search_fields is a sequence. za list or tuplerb   z
admin.E126)rH   rI   r-   N)r4   rb   rO   rP   rQ   )rE   rI   r   r   r   r     s    z%ModelAdminChecks._check_search_fieldsc             C   s~   |j dkrg S yt|j|j d
 }W n. ttfk
rR   tjd|j  |jddgS X t|t	j
t	jfsvtdd|dd	S g S dS )zA Check that date_hierarchy refers to DateField or DateTimeField. Nrp   zNThe value of 'date_hierarchy' refers to '%s', which does not refer to a Field.z
admin.E127)rI   r-   za DateField or DateTimeFielddate_hierarchyz
admin.E128)rH   rI   r-   )r   r   rU   r   r	   r   r2   ra   r4   r
   Z	DateFieldr   rQ   )rE   rI   rT   r   r   r   r     s    
z&ModelAdminChecks._check_date_hierarchyc       	      C   sz   |j  }g }xh|D ]`\}}}t|ds(qxH|jD ]>}d| }t||s0|jtjd|jj||jf |jdd q0W q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.z
admin.E129)rI   r-   )_get_base_actionsr   r   r1   r   r2   ra   r_   )	rE   rI   actionsr$   funcr   _Z
permissionmethod_namer   r   r   r     s"    

z1ModelAdminChecks._check_action_permission_methodsc             C   sD   dd |j  D }t|tt|kr@tjd|j |jddgS g S )z.Check that every action has a unique __name__.c             S   s   g | ]\}}}|qS r   r   )rK   r   r   r   r   r   rN     s    z>ModelAdminChecks._check_actions_uniqueness.<locals>.<listcomp>z<__name__ attributes of actions defined in %s must be unique.z
admin.E130)rI   r-   )r   rj   rk   r   r2   ra   )rE   rI   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   __classcell__r   r   )ra   r   r   o  s(   		$!	42r   c                   sX   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	dd Z
  ZS )InlineModelAdminChecksc                sR   | j | |j}t j|| j||| j||| j|| j|| j|| j	|S )N)
_check_has_add_permissionparent_modelr   r"   _check_relation_check_exclude_of_parent_model_check_extra_check_max_num_check_min_num_check_formset)rE   Z
inline_objr#   r   )ra   r   r   r"     s    



zInlineModelAdminChecks.checkc                s   t  j|}|rg S | j||r$g S |jd kr2g S t||j|jd}|j|jkrxtj	d|j|j
j|j
jf |jddgS g S d S )N)fk_namezYCannot exclude the field '%s', because it is the foreign key to the parent model '%s.%s'.z
admin.E201)rI   r-   )r   r<   r   ru   r   rU   r   r   r   r2   rV   r   r   ra   )rE   rI   r   r$   Zfk)ra   r   r   r     s    

z5InlineModelAdminChecks._check_exclude_of_parent_modelc             C   sV   yt ||j|jd W n6 tk
rL } ztj|jd |jddgS d }~X nX g S d S )N)r   r   z
admin.E202)rI   r-   )r   rU   r   
ValueErrorr   r2   argsra   )rE   rI   r   er   r   r   r     s
    &z&InlineModelAdminChecks._check_relationc             C   s$   t |jtstdd|ddS g S dS )z! Check that extra is an integer. z
an integerextraz
admin.E203)rH   rI   r-   N)r4   r   r   rQ   )rE   rI   r   r   r   r     s    z#InlineModelAdminChecks._check_extrac             C   s2   |j dkrg S t|j ts*tdd|ddS g S dS )z# Check that max_num is an integer. Nz
an integermax_numz
admin.E204)rH   rI   r-   )r   r4   r   rQ   )rE   rI   r   r   r   r   &  s
    
z%InlineModelAdminChecks._check_max_numc             C   s2   |j dkrg S t|j ts*tdd|ddS g S dS )z# Check that min_num is an integer. Nz
an integermin_numz
admin.E205)rH   rI   r-   )r   r4   r   rQ   )rE   rI   r   r   r   r   0  s
    
z%InlineModelAdminChecks._check_min_numc             C   s$   t |jtstdd|ddS g S dS )z2 Check formset is a subclass of BaseModelFormSet. r   formsetz
admin.E206)rw   rH   rI   r-   N)r   r   r   rx   )rE   rI   r   r   r   r   :  s    z%InlineModelAdminChecks._check_formsetc             C   sL   |j }y
|j}W n tk
r$   Y n$X t|}d|krHtjd|j t d S )NrI   zEUpdate %s.has_add_permission() to accept a positional `obj` argument.)ra   Zhas_add_permissionr   r   warningswarnr_   r   )rE   rI   r   r   r   r   r   r   r   B  s    
z0InlineModelAdminChecks._check_has_add_permission)r_   r   r   r"   r   r   r   r   r   r   r   r   r   r   )ra   r   r     s   

r   c             C   s   t jd|| f |j|dgS )NzThe value of '%s' must be %s.)rI   r-   )r   r2   ra   )r`   rH   rI   r-   r   r   r   rQ   Q  s    
rQ   c             C   s   t jd|| f |j|dgS )Nz)The value of '%s' must inherit from '%s'.)rI   r-   )r   r2   ra   )rw   rH   rI   r-   r   r   r   rx   [  s    
rx   c             C   s,   t jd|| |jjj|jjjf |j|dgS )NzGThe value of '%s' refers to '%s', which is not an attribute of '%s.%s'.)rI   r-   )r   r2   rU   rV   r   r   ra   )rT   rH   rI   r-   r   r   r   rX   e  s
    rX   )/r   	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.deprecationr   Zdjango.utils.inspectr   Zdjango.utils.module_loadingr   r   r   r&   r6   r7   r   r   rQ   rx   rX   r   r   r   r   <module>   s<   H   n  }g

