o 3aj@sDddlZddlZddlZddlZddlmZmZmZddlm Z ddl m Z ddl mZddlmZddlmZmZddlmZmZmZdd lmZdd lmZdd lmZdd lmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m Z m&Z&dd l'm(Z(m)Z)ddl*m+Z+ddl,m-Z-m.Z.m/Z/m0Z0ddl1m2Z2ddl3m4Z4m5Z5m6Z6ddl7m8Z8ddl9m:Z:m;Z;ddlZ>m?Z?m@Z@mAZAddlBmCZCmDZDddlEmFZFddlGmHZHddlImJZJmKZKddlLmMZMddlNmOZOddlPmQZQddlRmSZSddlTmUZUddlVmWZWmXZXmYZYmZZZm[Z[ddl\m]Z^m_Z_dd l`maZadd!lbmcZcd"Zdd#Zed$\ZfZgd%d&Zhd'd(ZiGd)d*d*ejZke4jle jmejnd+e4jod,ejpie4jqd,ejrie4jsd,ejtie4jud,ejvie4jwd,ejxie4jyd,ejzie4j{d,ej|ie4j}d,ej~ie4jd,ej~ie4jd,ejie4jd,ejii ZeOeaZGd-d.d.e jd/ZGd0d1d1eZGd2d3d3eZGd4d5d5eZGd6d7d7eZdS)8N)partialreduceupdate_wrapper)quote)forms)settings)messages)helperswidgets)BaseModelAdminChecksInlineModelAdminChecksModelAdminChecks)display)DisallowedModelAdminToField)add_preserved_filters) NestedObjectsconstruct_change_messageflatten_fieldsetsget_deleted_objectslookup_needs_distinctmodel_format_dictmodel_ngettextrunquote)AutocompleteSelectAutocompleteSelectMultiple)get_permission_codename)FieldDoesNotExist FieldErrorPermissionDeniedValidationError) Paginator)modelsrouter transaction) LOOKUP_SEP)DELETION_FIELD_NAME all_valid)BaseInlineFormSetinlineformset_factorymodelform_defines_fieldsmodelform_factorymodelformset_factory)CheckboxSelectMultipleSelectMultiple)HttpResponseRedirect)HttpResponseBase)SimpleTemplateResponseTemplateResponse)reverse)method_decorator) format_html) urlencode) mark_safe)capfirst format_lazy get_text_list smart_splitunescape_string_literal)gettextngettext) csrf_protect) RedirectView_popup _to_field)cCsddlm}|jj|ddS)Nr) ContentTypeF)for_concrete_model)"django.contrib.contenttypes.modelsrDobjects get_for_model)objrDrJ>/usr/lib/python3/dist-packages/django/contrib/admin/options.pyget_content_type_for_model=s rLcCs|tkrdSdS)N radiolistzradiolist inline)VERTICAL) radio_stylerJrJrK get_ul_classDrPc@s eZdZdS)IncorrectLookupParametersN)__name__ __module__ __qualname__rJrJrJrKrRHsrR) form_classwidgetrWc@sBeZdZdZdZdZdZdZdZe j Z dZ dZ iZiZiZdZdZdZdZdZeZddZddZd d Zd d Zd dZddZddZddZd;ddZ ddZ!d;ddZ"d;ddZ#d;ddZ$dd Z%d!d"Z&d;d#d$Z'd;d%d&Z(d'd(Z)d)d*Z*d+d,Z+d-d.Z,d/d0Z-d;d1d2Z.d;d3d4Z/d;d5d6Z0d;d7d8Z1d9d:Z2dS)<BaseModelAdminz8Functionality common to both ModelAdmin and InlineAdmin.rJNTcKs|j|fi|SN) checks_classcheck)selfkwargsrJrJrKr[yzBaseModelAdmin.checkcCs:tt}|jD] \}}||i|q ||_dSrY)copydeepcopyFORMFIELD_FOR_DBFIELD_DEFAULTSformfield_overridesitems setdefaultupdate)r\ overrideskvrJrJrK__init__|s  zBaseModelAdmin.__init__cKsZ|jr |j||fi|St|tjtjfr|j|jvr&i|j|j|}t|tjr7|j||fi|}nt|tjrG|j ||fi|}|r|j |j vr|j j |jj}i}|rq|j||||||||dtj|j|j|j fi||_|S|jD]}||jvrit|j||}|jdi|Sq|jdi|S)z Hook for specifying the form Field instance for a given database Field instance. If kwargs are given, they're passed to the form Field's constructor. )can_add_relatedcan_change_relatedcan_delete_relatedcan_view_relatedNrJ)choicesformfield_for_choice_field isinstancer! ForeignKeyManyToManyField __class__rbformfield_for_foreignkeyformfield_for_manytomanyname raw_id_fields admin_site _registryget remote_fieldmodelrehas_add_permissionhas_change_permissionhas_delete_permissionhas_view_permissionr RelatedFieldWidgetWrapperrWmror_r` formfield)r\db_fieldrequestr]rrelated_modeladminwrapper_kwargsklassrJrJrKformfield_for_dbfields>      z$BaseModelAdmin.formfield_for_dbfieldcKsj|j|jvr-d|vrtjdt|j|jid|d<d|vr-|j|jdtdfgd|d<|jd i|S) zR Get a form Field for a database Field that has declared choices. rWclassattrsrnNone) include_blank blank_choiceNrJ) rv radio_fieldsr AdminRadioSelectrP get_choicesblank_r)r\rrr]rJrJrKros    z)BaseModelAdmin.formfield_for_choice_fieldcCsN|jj|jj}|dur%||}|dur%|dkr%|jjj|j|SdS)z If the ModelAdmin specifies ordering, the queryset should respect that ordering. Otherwise don't specify the queryset, let the field decide (return None in that case). NrJ) rxryrzr{r| get_ordering_default_managerusingorder_by)r\dbrr related_adminorderingrJrJrKget_field_querysets  z!BaseModelAdmin.get_field_querysetcKs|d}d|vrP|j||vrt||j|d|d<n4|j|jvr/tj|j|j|d|d<n!|j|j vrPtj dt |j |jid|d<|j rLt dnd|d<d |vrc||||}|durc||d <|jd i|S) z4 Get a form Field for a ForeignKey. rrWrrrrN empty_labelquerysetrJ)rzrvget_autocomplete_fieldsrrxrwr ForeignKeyRawIdWidgetr{rrrPrrrr)r\rrr]rrrJrJrKrts    z'BaseModelAdmin.formfield_for_foreignkeyc Ks|jjjjsdS|d}d|vrQ||}|j|vr&t||j|d|d<n+|j|j vr9t j |j|j|d|d<n|jg|j |j vrQt |j|j|j v|d<d|vrd||||}|durd||d<|jdi|}t|jtrt|jttfstd}|j} | rtd| |n||_|S) z9 Get a form Field for a ManyToManyField. NrrWrruLHold down “Control”, or “Command” on a Mac, to select more than one.z{} {}rJ)r{through_meta auto_createdrzrrvrrxrwr ManyToManyRawIdWidgetfilter_verticalfilter_horizontalFilteredSelectMultiple verbose_namerrrprWr-r,r help_textr8) r\rrr]rautocomplete_fieldsr form_fieldmsgrrJrJrKrusD        z'BaseModelAdmin.formfield_for_manytomanycC|jS)zw Return a list of ForeignKey and/or ManyToMany fields which should use an autocomplete widget. )rr\rrJrJrKrz&BaseModelAdmin.get_autocomplete_fieldscCsN|dus|js dSt|jr||St|dr%tdt|j|jddSdS)Nget_absolute_urlzadmin:view_on_site)content_type_id object_id)r]) view_on_sitecallablehasattrr2rLpkr\rIrJrJrKget_view_on_site_url%s    z#BaseModelAdmin.get_view_on_site_urlcCs,zt|jWStyt|jjYSw)zP Return the empty_value_display set on ModelAdmin or AdminSite. )r6empty_value_displayAttributeErrorrxr\rJrJrKget_empty_value_display2s   z&BaseModelAdmin.get_empty_value_displaycCr)z. Hook for specifying exclude. )excluder\rrIrJrJrK get_exclude;zBaseModelAdmin.get_excludecCs.|jr|jS|||}g|j|||S)z- Hook for specifying fields. )fields_get_form_for_get_fields base_fieldsget_readonly_fields)r\rrIformrJrJrK get_fieldsAs zBaseModelAdmin.get_fieldscCs"|jr|jSdd|||ifgS)z0 Hook for specifying fieldsets. Nr) fieldsetsrrrJrJrK get_fieldsetsKszBaseModelAdmin.get_fieldsetscCr)z#Hook for specifying custom inlines.)inlinesrrJrJrK get_inlinesSzBaseModelAdmin.get_inlinescCs |jpdS)z5 Hook for specifying field ordering. rJ)rrrJrJrKrWs zBaseModelAdmin.get_orderingcCr)z= Hook for specifying custom readonly fields. )readonly_fieldsrrJrJrKr]rz"BaseModelAdmin.get_readonly_fieldscCr)zA Hook for specifying custom prepopulated fields. )prepopulated_fieldsrrJrJrKget_prepopulated_fieldscrz&BaseModelAdmin.get_prepopulated_fieldscCs(|jj}||}|r|j|}|S)z Return a QuerySet of all model instances that can be edited by the admin site. This is used by changelist_view. )r|r get_querysetrr)r\rqsrrJrJrKris   zBaseModelAdmin.get_querysetcCs|jdur|jS||S)zAHook for specifying which fields can be sorted in the changelist.N) sortable_byget_list_displayrrJrJrKget_sortable_byuszBaseModelAdmin.get_sortable_byc Csbddlm}|j}|jjD]}t|r|}||ft|vr$dSq g}d}| t D]:}z|j |} Wn t yBYn'w|rQ|j rV| |djvrV||t| dds^n | }| djj}q.t|dkrqdS|jh} |jD]'} t| trt| |r| | jqxt| ttfr| | dqx| | qxt |t ||gh|  S)Nr)SimpleListFilterT get_path_inforB)django.contrib.admin.filtersrr|rrelated_fkey_lookupsrr url_params_from_lookup_dictrcsplitr$ get_fieldr is_relationr target_fieldsappendgetattrto_optslendate_hierarchy list_filterrptype issubclassaddparameter_namelisttuplejoin isdisjoint) r\lookupvaluerr| fk_lookuprelation_parts prev_fieldpartfield valid_lookups filter_itemrJrJrKlookup_allowedysJ         zBaseModelAdmin.lookup_allowedc s|jj}z||}Wn tyYdSw|jrdS|jD] }||kr)dSqt}|jj D]\}}| ||j D]} | | jq?q3dd|j ddD} | D]"} | j| jj} tfdd|Drxt| drx| |krxdSqVdS)z Return True if the model associated with this admin should be allowed to be referenced by the specified field. FTcss |] }|jr|js|VqdSrY)rconcrete.0frJrJrK s z2BaseModelAdmin.to_field_allowed..)include_hiddenc3s|]}t|VqdSrY)r)rr| related_modelrJrKrget_related_field)r|rrr primary_key many_to_manym2m_target_field_namesetrxryrcrrrrrr{anyrr) r\rto_fieldoptsrrregistered_modelsr|admininlinerelated_objectsrelated_objectr{rJrrKto_field_alloweds>       zBaseModelAdmin.to_field_allowedcCs&|j}td|}|jd|j|fS)z Return True if the given request has permission to add an object. Can be overridden by the user in subclasses. r%s.%srruserhas_perm app_label)r\rrcodenamerJrJrKr}s z!BaseModelAdmin.has_add_permissioncC&|j}td|}|jd|j|fS)a Return True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the `obj` parameter. Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to change the `obj` model instance. If `obj` is None, this should return True if the given request has permission to change *any* object of the given type. changerrr\rrIrrrJrJrKr~ z$BaseModelAdmin.has_change_permissioncCr)a Return True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the `obj` parameter. Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to delete the `obj` model instance. If `obj` is None, this should return True if the given request has permission to delete *any* object of the given type. deleterrrrJrJrKrrz$BaseModelAdmin.has_delete_permissioncCsF|j}td|}td|}|jd|j|fp"|jd|j|fS)a Return True if the given request has permission to view the given Django model instance. The default implementation doesn't examine the `obj` parameter. If overridden by the user in subclasses, it should return True if the given request has permission to view the `obj` model instance. If `obj` is None, it should return True if the request has permission to view any object of the given type. viewrrr)r\rrIr codename_viewcodename_changerJrJrKrs   z"BaseModelAdmin.has_view_permissioncCs|||p |||SrY)rr~rrJrJrKhas_view_or_change_permissionsz,BaseModelAdmin.has_view_or_change_permissioncCs|j|jjS)a Return True if the given request has any permission in the given app label. Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to view the module on the admin index page and access the module's index page. Overriding it does not restrict access to the add, change or delete views. Use `ModelAdmin.has_(add|change|delete)_permission` for that. )rhas_module_permsrrrrJrJrKhas_module_permissions z$BaseModelAdmin.has_module_permissionrY)3rSrTrU__doc__rrwrrrr ModelFormrrrrrrbrrrrshow_full_result_countr rZr[rirrorrtrurrrrrrrrrrrrrrr}r~rrrrrJrJrJrKrXds\9 *      6-    rX) metaclasscseZdZdZdZdZdZdZdZdZ dZ dZ dZ dZ dZdZeZdZgZdZdZdZdZdZdZdZgZejZdZdZ dZ!e"Z#fd d Z$d d Z%dd dZ&ddZ'e(ddZ)e(ddZ*ddZ+ddZ,dddZ-ddZ.ddZ/ddd Z0d!d"Z1d#d$Z2dd%d&Z3dd(d)Z4d*d+Z5d,d-Z6d.d/Z7e8e9d0d1d2d3Z:e;d4d5Zd:d;Z?e@jAfdd?ZCd@dAZDdBdCZEdDdEZFdFdGZGdHdIZHdJdKZIdLdMZJddNdOZKeLjMdPdfdQdRZNdSdTZOdUdVZPdWdXZQdYdZZRd[d\ZSd]d^ZTdd_d`ZUddadbZVdcddZWdedfZXdgdhZYdidjZZdkdlZ[dmdnZ\dodpZ]ddqdrZ^dsdtZ_dudvZ`eaddwdxZbdydzZcdd{d|Zddd}d~ZeddZfddZgeadddZhddZieadddZjddZkdddZlddZmZnS) ModelAdminzBEncapsulate all admin options and functionality for a given model.)__str__rJFdNTcs"||_|j|_||_tdSrY)r|rrrxsuperri)r\r|rxrsrJrKriKszModelAdmin.__init__cCsd|jjj|jjfS)Nr)r|rrrsrSrrJrJrKr%Qr^zModelAdmin.__str__cCsng}|||D],}||j|j}|r/|||s&|||s&|||s&q|||s/d|_||q|S)Nr)rr|rxrr}rmax_numr)r\rrIinline_instances inline_classr rJrJrKget_inline_instancesTs     zModelAdmin.get_inline_instancesc sddlm}fdd}jjjjjjf}|d|jd|d|d|jd |d|d |jd |d|d |j d |d|d|j d|d|d|t j dj jf|dgS)Nr)pathcsfdd}|_t|S)Ncsj|i|SrY)rx admin_view)argsr])r\rrJrKwrappergr^z2ModelAdmin.get_urls..wrap..wrapper) model_adminr)rr1r)rrKwrapfs z!ModelAdmin.get_urls..wraprz%s_%s_changelist)rvzadd/z %s_%s_addz/history/z %s_%s_historyz/delete/z %s_%s_deletez/change/z %s_%s_changez/z%s:%s_%s_change) pattern_name) django.urlsr.r|rr model_namechangelist_viewadd_view history_view delete_view change_viewr?as_viewrxrv)r\r.r3inforJrrKget_urlscs   zModelAdmin.get_urlscCs|SrY)r>rrJrJrKurlszszModelAdmin.urlsc Cs@tjrdnd}d|dddddd d |g}tjd d |Dd S)Nr.minvendor/jquery/jquery%s.jsjquery.init.jszcore.jszadmin/RelatedObjectLookups.jsz actions.jsz urlify.jszprepopulate.jszvendor/xregexp/xregexp%s.jscSg|]}d|qSz admin/js/%srJrurlrJrJrK z$ModelAdmin.media..js)rDEBUGrMediar\extrarJrJrJrKmedia~s zModelAdmin.mediacCs&||||||||dS)z Return a dict of all perms for this model. This dict has the keys ``add``, ``change``, ``delete``, and ``view`` mapping to the True/False for each of those actions. )rrrr)r}r~rrrrJrJrKget_model_permss zModelAdmin.get_model_permscCs|j||ddSN)r)get_formrrJrJrKrrQz#ModelAdmin._get_form_for_get_fieldsc s`d|vr |d}nt||}||}|durgnt|}||}|||r?t|dr?||s?|||durVtj drVj j j rV|j j j |pYd}t fdd|D} tj jj f| } | ||tj|dd|} | ddurt| d stj| d<z tjfi| WSty} z td | jjfd} ~ ww) zv Return a Form class for use in the admin add view. This is used by add_view and change_view. rNrrc3s |] }|jjvr|VqdSrY)rdeclared_fieldsrrrJrKrsz&ModelAdmin.get_form..r)rrrformfield_callbackrz:%s. Check fields/fieldsets/exclude attributes of class %s.)poprrrrrextendrr~rrrdictfromkeysrrSrrr)r ALL_FIELDSr*r|rrs) r\rrIrr]rexcludedrr new_attrsrdefaultserJrrKrRsB        zModelAdmin.get_formcKsddlm}|S)zM Return the ChangeList class for use on the changelist page. r) ChangeList)django.contrib.admin.views.mainr_)r\rr]r_rJrJrKget_changelists zModelAdmin.get_changelistcCsz||}|||}||rdg|}||}||}|||j|||||j||| ||j |j |j || S)zs Return a `ChangeList` instance based on `request`. May raise `IncorrectLookupParameters`. action_checkbox) rget_list_display_links get_actionsrrar|get_list_filterrget_search_fieldsget_list_select_related list_per_pagelist_max_show_all list_editable)r\r list_displaylist_display_linksrr_rJrJrKget_changelist_instances*      z"ModelAdmin.get_changelist_instancec Csl||}|j}|dur|jjn|j|}z||}|jdi|j|iWS|jt t fy5YdSw)z Return an instance matching the field and value provided, the primary key is used if no field is provided. Return ``None`` if no match is found or the object_id fails validation. NrJ) rr|rrr to_pythonrzrv DoesNotExistr ValueError)r\rr from_fieldrr|rrJrJrK get_objects  zModelAdmin.get_objectcKsNdt|j|di|}|ddurt|dstj|d<t|jfi|S)zT Return a Form class for use in the Formset on the changelist page. rUrTrNr)rrrzr)rrZr*r|r\rr]r]rJrJrKget_changelist_forms zModelAdmin.get_changelist_formcKs8dt|j|di|}t|j||fd|jd|S)zi Return a FormSet class for use on the changelist page if list_editable is used. rUrTr)rNr)rrr+r|rtrjrsrJrJrKget_changelist_formset s z!ModelAdmin.get_changelist_formsetccs*|||D] }||||fVqdS)z? Yield formsets and the corresponding inlines. N)r- get_formset)r\rrIr rJrJrKget_formsets_with_inlinessz$ModelAdmin.get_formsets_with_inlinesrcCs|||||SrY) paginator)r\rrper_pageorphansallow_empty_first_pagerJrJrK get_paginator!rQzModelAdmin.get_paginatorcC8ddlm}m}|jj|jjt|j|jt|||dS)z Log that an object has been successfully added. The default implementation creates an admin LogEntry object. r)ADDITIONLogEntryuser_idrr object_repr action_flagchange_message) django.contrib.admin.modelsr~rrG log_actionrrrLstr)r\robjectmessager~rrJrJrK log_addition$zModelAdmin.log_additioncCr})z Log that an object has been successfully changed. The default implementation creates an admin LogEntry object. r)CHANGErr) rrrrGrrrrLr)r\rrrrrrJrJrK log_change4rzModelAdmin.log_changecCs2ddlm}m}|jj|jjt|j|j||dS)z Log that an object will be deleted. Note that this method must be called before the deletion. The default implementation creates an admin LogEntry object. r)DELETIONr)rrrrr)rrrrGrrrrL)r\rrrrrrJrJrK log_deletionDszModelAdmin.log_deletionz*) descriptioncCstjtjt|jS)zE A list_display column containing a checkbox widget. )r checkboxrenderACTION_CHECKBOX_NAMErrrrJrJrKrbTszModelAdmin.action_checkboxcCst|dt|ddS)Nshort_descriptionr )rr7replace)funcrvrJrJrK_get_action_description[sz"ModelAdmin._get_action_descriptioncs~g}fddjp gD}dd|D}dd|D}jjD]\}}||vr)q ||}||||fq |||S)zAReturn the list of actions, prior to any request-based filtering.c3s|]}|VqdSrY) get_actionractionrrJrKrbrz/ModelAdmin._get_base_actions..cSsg|]}|r|qSrJrJrrJrJrKrGdrHz0ModelAdmin._get_base_actions..cSsh|]\}}}|qSrJrJ)rrrvrJrJrK esz/ModelAdmin._get_base_actions..)actionsrxrrrW)r\r base_actionsbase_action_namesrvrrrJrrK_get_base_actions_s  zModelAdmin._get_base_actionscsdg}|D]+}|d}t|ds||qfdd|jD}tfdd|Dr/||q|S)z.c3s|]}|VqdSrYrJ)rhas_permissionrTrJrKr})rrrr)r\rrfiltered_actionsrrpermission_checksrJ)rr\rK_filter_actions_by_permissionsqs    z)ModelAdmin._filter_actions_by_permissionscCs6|jdus t|jvr iS|||}dd|DS)z Return a dictionary mapping the names of all actions for this ModelAdmin to a tuple of (callable, name, description) for each action. NcSsi|] \}}}||||fqSrJrJ)rrrvdescrJrJrK z*ModelAdmin.get_actions..)r IS_POPUP_VARGETrr)r\rrrJrJrKrdszModelAdmin.get_actionscCsBg|}||D]\}}}||t|jf}||q |S)zy Return a list of choices for use in a form object. Each choice is a tuple (name, description). )rdvaluesrrr)r\rdefault_choicesrnrrvrchoicerJrJrKget_action_choicess  zModelAdmin.get_action_choicescCsjt|r |}|j}n t|j|rt|j|}nz|j|}Wn ty)YdSw|||}|||fS)z Return a given action from a parameter, which can either be a callable, or the name of a method on the ModelAdmin. Return is a tuple of (callable, name, description). N) rrSrrsrrxrKeyErrorr)r\rrrrJrJrKrs    zModelAdmin.get_actioncCr)zd Return a sequence containing the fields to be displayed on the changelist. )rkrrJrJrKrrzModelAdmin.get_list_displaycCs*|js |jdus |s |jSt|ddS)z Return a sequence containing the fields to be displayed as links on the changelist. The list_display parameter is the list of fields returned by get_list_display(). NrB)rlr)r\rrkrJrJrKrcsz!ModelAdmin.get_list_display_linkscCr)z Return a sequence containing the fields to be displayed as filters in the right sidebar of the changelist page. )rrrJrJrKrerzModelAdmin.get_list_filtercCr)zt Return a list of fields to add to the select_related() part of the changelist items query. )list_select_relatedrrJrJrKrgrz"ModelAdmin.get_list_select_relatedcCr)zz Return a sequence containing the fields to be searched whenever somebody submits a search query. ) search_fieldsrrJrJrKrfrzModelAdmin.get_search_fieldscsfddd}|}|rQ|rQfdd|D}t|D]%dr1ddkr1tfd d|D}ttj|q|tfd d |DO}|fS) z Return a tuple containing a queryset to implement the search and a boolean indicating if the results may contain duplicates. c s|dr d|ddS|drd|ddS|dr'd|ddSjj}|t}d}|D]6}|dkr>|jj}z||}Wnty[|rY| |rY|YSYq4w|}t |d rj| d j }q4d |S) N^z%s__istartswithrB=z %s__iexact@z %s__searchrrrz %s__icontains) startswithr|rrr$rrvrr get_lookuprrr) field_namer lookup_fieldsr path_partrrrJrKconstruct_searchs0       z7ModelAdmin.get_search_results..construct_searchFcsg|]}t|qSrJ)r)r search_field)rrJrKrGsz1ModelAdmin.get_search_results..)"'rrcs g|] }tjdi|iqS)rJ)r!Q)r orm_lookup)bitrJrKrGsc3s|] }tj|VqdSrY)rr)r search_specrrJrKr s  z0ModelAdmin.get_search_results..) rfr:rr;filterroperatoror_r)r\rr search_termmay_have_duplicatesr orm_lookups or_queriesrJ)rrrr\rKget_search_resultss$      zModelAdmin.get_search_resultscCsl|j}|jr4|r4|jj}d|j|jf}d|j|jf}||kr&|j }n|j d}|r4t d|iSdS)z; Return the preserved filters querystring. z%s:%sadmin:%s_%s_changelist_changelist_filtersr) resolver_matchpreserve_filtersr|rapp_nameurl_namerr6rr5rz)r\rmatchr current_urlchangelist_urlpreserved_filtersrJrJrKget_preserved_filterss    z ModelAdmin.get_preserved_filterscCs t|||S)zV Construct a JSON structure describing changes from a changed object. )r)r\rrformsetsrrJrJrKr! z#ModelAdmin.construct_change_messagercCsvt|ts/z ttj|}Wnty.tjj}d dd|D}t d||fwtj |||||ddS)a Send a message to the user. The default implementation posts a message using the django.contrib.messages backend. Exposes almost the same API as messages.add_message(), but accepts the positional arguments in a different order to maintain backwards compatibility. For convenience, it accepts the `level` argument as a string rather than the usual level number. z, css|]}d|VqdS)z`%s`NrJ)rlevelrJrJrKr8rz*ModelAdmin.message_user..z7Bad message level string: `%s`. Possible values are: %s) extra_tags fail_silentlyN) rpintrr constantsupperr DEFAULT_TAGSrrrp add_message)r\rrrrrlevels levels_reprrJrJrK message_user's   zModelAdmin.message_usercCs |jddS)z Given a ModelForm return an unsaved instance. ``change`` is True if the object is being changed, and False if it's being added. F)commitsave)r\rrrrJrJrK save_form@ zModelAdmin.save_formcC |dS)zA Given a model instance save it to the database. Nr)r\rrIrrrJrJrK save_modelGrzModelAdmin.save_modelcCr)zE Given a model instance delete it from the database. NrrrJrJrK delete_modelMrzModelAdmin.delete_modelcCr)z.Given a queryset, delete it from the database.Nrr\rrrJrJrKdelete_querysetSs zModelAdmin.delete_querysetcCs |dS)zB Given an inline formset save it to the database. Nr)r\rrformsetrrJrJrK save_formsetWrzModelAdmin.save_formsetcCs(||D] }|j||||dqdS)aO Given the ``HttpRequest``, the parent ``ModelForm`` instance, the list of inline formsets and a boolean value based on whether the parent is being added or changed, save the related objects to the database. Note that at this point save_form() and save_model() have already been called. rN)save_m2mr)r\rrrrrrJrJrK save_related]szModelAdmin.save_relatedcCsn|jj}|j}||} t| |d|}||} d} |dD]} | js*| js*| jr.d} nq| id|d|d| ||d||d |||d |||d | d |d j pht dd|dDd| dud| d|d|dt|jjd|jd|jdtdtd|i|r|jdur|j} n|j} |jj|_t|| pd||jfd|dg|S)NrrFinline_admin_formsetsTrrrr}r~r"has_editable_inline_admin_formsetshas_file_field adminformcss|]}|jVqdSrY)r is_multipart)r admin_formsetrJrJrKr|s  z0ModelAdmin.render_change_form..has_absolute_url absolute_urlform_urlrrsave_as save_on_top to_field_var is_popup_varrzadmin/%s/%s/change_form.htmlzadmin/%s/change_form.htmlzadmin/change_form.html)r|rrrrrr}r~rrerrrrrLrrr TO_FIELD_VARradd_form_templatechange_form_templaterxrv current_appr1r6)r\rcontextrrrrIrrrview_on_site_urlrr  form_templaterJrJrKrender_change_formisz            zModelAdmin.render_change_formcCs|j}||}td|j|jft|jf|jjd}| ||r*t dt ||}nt |}|j |d}t|jvrs|jt} | rFt | } n|jjj} || } tt | t |d} t||jpnd|j|jfd|jdgd | iSd |jvsd |jvr|jr| ||rtd } | ||r| d td7} ||t | fi|tj|dur|}t||d|}t|Sd|jvrt tdfi|} ||| tj|j}t||d|}t|St td fi|} ||| tj| ||S)zD Determine the HttpResponse for the add_view stage. admin:%s_%s_changer0r{}rvrI)rrIadmin/%s/%s/popup_response.htmladmin/%s/popup_response.htmladmin/popup_response.htmlpopup_response_data _continue _saveasnewu.The {name} “{obj}” was added successfully.rzYou may edit it again below.Nr _addanotheruPThe {name} “{obj}” was added successfully. You may add another {name} below.)!rrr2rr6rrrxrvr~r4urlquoterrrPOSTrzrattnameserializable_valuejsondumpsr1popup_response_templatesave_as_continuerrrSUCCESSrr.r.response_post_save_add)r\rrIpost_url_continuerrobj_urlobj_reprmsg_dictrattrrrr redirect_urlrJrJrK response_adds~              zModelAdmin.response_addc Cst|jvrJ|j}|jt}|rt|n|jj}|jj d}| |}t dt|t|t|d}t ||jpEd|j|jfd|jdgd|iS|jj}||} |jtdt|j|d } d |jvrttd fi| } ||| tj|j} t| |d | } t| Sd |jvrttdfi| } ||| tjtd|j|jf|jf|jjd} t| |d | } t| Sd|jvrttdfi| } ||| tjtd|j|jf|jjd} t| |d | } t| Sttdfi| } ||| tj| ||S)zG Determine the HttpResponse for the change_view stage. rr)rrrI new_valuerrrrr rruMThe {name} “{obj}” was changed successfully. You may edit it again below.rruKThe {name} “{obj}” was added successfully. You may edit it again below.r r ruRThe {name} “{obj}” was changed successfully. You may add another {name} below.zadmin:%s_%s_addru0The {name} “{obj}” was changed successfully.)!rrrrzrrrrrr]rrrr1rrr6r|rrr4rr.rrrrrr.r2rxrvresponse_post_save_change) r\rrIrrr$rr'rrr#rr%rJrJrKresponse_changes            zModelAdmin.response_changecCsh|jj}||r(td|j|jf|jjd}||}t ||d|}t |Std|jjd}t |S)Nrr(r admin:index) r|rrr2rr6rxrvrrr.)r\rrIrpost_urlrrJrJrK_response_post_save0s   zModelAdmin._response_post_savecC |||S)zy Figure out where to redirect after the 'Save' button has been pressed when adding a new object. r-rrJrJrKr=rz!ModelAdmin.response_post_save_addcCr.)z Figure out where to redirect after the 'Save' button has been pressed when editing an existing object. r/rrJrJrKr)Drz$ModelAdmin.response_post_save_changec CsTz t|jdd}Wn tyd}Ynw|j}|tjd|ddz|d| d|iWn t y@Ynw|j |dd}| ||j d_|r|jd}|jd}|||d}|j tj} | s|std} ||| tjdS|s|j| d}||||} t| tr| St|Std } ||| tjdS) z Handle an admin action. This is called if a request is POSTed to the changelist; it returns an HttpResponse if the action was handled, and None otherwise. indexrNrauto_id select_acrossWItems must be selected in order to perform actions on them. No items have been changed.pk__inzNo action selected.)rrrzrpr_rVr rregetlist IndexError action_formrrrnis_valid cleaned_datardrrrWARNINGrrpr/r. get_full_path) r\rr action_indexdatar9rr3rselectedrresponserJrJrKresponse_actionKsB           zModelAdmin.response_actioncCs|jj}t|jvr*tdt|d}t||jp%d|j |j fd|j dgd|iS| |t d|j |dtj||d r_td |j |j f|jjd }||}t||d |}t|Std |jjd }t|S)zG Determine the HttpResponse for the delete_view stage. r)rrrrrru4The %(name)s “%(obj)s” was deleted successfully.rNrr(rr+)r|rrrrrrr1rrr6rrrrrr~r2rxrvrrr.)r\r obj_displayobj_idrrr,rrJrJrKresponse_deletesD     zModelAdmin.response_deletecCsR|jj}|j}|jj|_|jtt|j dt ||j p&d ||j d |dg|S)N)rrrOz$admin/{}/{}/delete_confirmation.htmlz!admin/{}/delete_confirmation.htmlzadmin/delete_confirmation.html)r|rrrxrvrrerrrOr1delete_confirmation_templateformatr6)r\rrrrrJrJrKrender_delete_forms"  zModelAdmin.render_delete_formc Cs|r|||n||}g}t||D]W\}}t|||} t|||} |r=|||} |||} |||} n d} } } d|_|_| ||}t | ||}t j ||| || || | | |d }||q|S)NFr)r2r}r~rr)r~r}ziprrrrrNr*rrXrr InlineAdminFormSetr)r\rrr+rIcan_edit_parentrr rrreadonlyr}r~rr prepopulatedinline_admin_formsetrJrJrKget_inline_formsetss(       zModelAdmin.get_inline_formsetsc Cs`t|j}|D]$}z |jj|}Wn tyYq wt|tj r-|| d||<q |S)zJ Get the initial form data from the request's GET params. ,) rXrrcr|rrrrpr!rrr)r\rinitialrgrrJrJrKget_changeform_initial_datas  z&ModelAdmin.get_changeform_initial_datacCs@td|jt|d}|||tjtd|jjd}t |S)z Create a message informing the user that the object doesn't exist and return a redirect to the admin index page. uG%(name)s with ID “%(key)s” doesn’t exist. Perhaps it was deleted?)rvkeyr+r() rrrrrr<r2rxrvr.)r\rrrrrFrJrJrK _get_obj_does_not_exist_redirectsz+ModelAdmin._get_obj_does_not_exist_redirectcCsHtjt|jd|||||WdS1swYdSNr)r#atomicr" db_for_writer|_changeform_viewr\rrr extra_contextrJrJrKchangeform_views$zModelAdmin.changeform_viewcCs|jt|jt}|r|||std||j}|j}|jdkr+d|jvr+d}|du}|r;| |s8t d} n*| |t ||} |jdkrR| || sQt n||| sZt | dure||||S||| } |j|| | t| d} |jdkr| |j|j| d} | } | r|j|| | d}n| j}|j||| d\}}t|r| r|||| | ||| || ||| ||}|r|||||||S|||||||Sd} n'|r| |}| |d} |j|| jdd\}}n| | d} |j|| d d\}}|s| || st| }n|!|| }t"j#| t$| |s.| || r4|%|| ni||d }|j&|j&}|'|||| }|D]}||j&}qJ|r[t(d }n| || rgt(d }nt(d }i|j)*|||j+| r}t,| nd||| t-|jvpt-|jv|||t".| ||/|d }|jdkr| sd|jvrd|d<d|d<d}|0|pi|j1|||| | |dS)N"The field %s cannot be referenced.rr)rr)instancerF)rQT)r2zAdd %sz Change %szView %s) titlesubtitlerroriginalis_popuprrOrerrorsr show_saveshow_save_and_continue)rrrIr)2rrzrrrrr|rmethodr}rrrrr~rrTrrRrFILESr:rr]_create_formsetsr&rrrrr&rr*rRrr AdminFormrrrOrOrrx each_contextrrrAdminErrorListrrer )r\rrrrZrr|rrrIrr!rform_validated new_objectrr+rrQr adminFormrOinline_formsetsinline_formsetr^rrJrJrKrXs               "     zModelAdmin._changeform_viewcCs||d||SrYr[)r\rrrZrJrJrKr8xrQzModelAdmin.add_viewcCs|||||SrYrprYrJrJrKr;{rQzModelAdmin.change_viewcs8tdt||jjjjfdd|j DS)z6Return POST data values of list_editable primary keys.z {}-\d+-{}$csg|] \}}|r|qSrJ)r)rrSr pk_patternrJrKrGrz5ModelAdmin._get_edited_object_pks..) recompilerGescaper|rrrvrrc)r\rprefixrJrqrK_get_edited_object_pks~sz!ModelAdmin._get_edited_object_pkscCs\|||}||}|jjjj}z |D]}||qWn ty'|YSw|j|dS)zr Based on POST data, return a queryset of the objects that were edited via list_editable. r5)rwrr|rrrnrr)r\rrv object_pksrvalidaterrJrJrK_get_list_editable_querysets      z&ModelAdmin._get_list_editable_querysetcCsddlm}|jj}|j}||stz||}Wn$ty?||j vr2t ddt diYSt |j d|dYSwd}|jtj}||} | r|jd krd |jvrd |jvr|rr|j|||d } | ro| Sd }nt d} ||| tjd }| r|jd krtj|jvrd |jvrd |jvr|r|j|||d } | r| Sd }|rt |Sd} |_|jd krD|jrDd |jvrD||st||} ||| }| |j|j |d } |_| !rCd}| j"D]3}|#r#|j$||d d}|j%|||d d|j&||gd d|'||d}|(||||d7}q|r=t)dd||t*||d} ||| tj+t |Sn|jr\||r\||} | |j,d } |_| rf|j-| j-}n|j-}| r|j.dd}|/||j0d_1||j-7}nd}t)dd|j2}i|j34|idt5|j6dt ddt7|j,id|d|j2id|j8d dd!|j9d"|j:d#|d$|d%|;|d&|j<d'|d(|j=d)|j>d*|j?d+|@||pi}|j3jA|_BtC||jDpd,||jEfd-|d.g|S)/z> The 'change list' admin view for this model. r) ERROR_FLAGzadmin/invalid_setup.htmlr^zDatabase error?z=1Frr0_saverTr4Nr)rrrBz,%(count)s %(name)s was changed successfully.z-%(count)s %(name)s were changed successfully.)countrvr1rz%(total_count)s selectedzAll %(total_count)s selected module_nameselection_notez0 of %(cnt)s selectedcntselection_note_all total_countr_rarclrOr}rr9actions_on_topactions_on_bottomactions_selection_counterrzadmin/%s/%s/change_list.htmlzadmin/%s/change_list.htmlzadmin/change_list.html)Fr`r{r|rrrrrmrRrr0rr.r.rr7r rrdrerBrrrr<r=rrjr~rurzget_default_prefixrfr:r has_changedrrrrrr=rr result_listrOr9rrrn result_countrxrirverbose_name_pluralrr^rarr}rrrrrrvrr1change_list_templater6)r\rrZr{rrr action_failedr@rrArrFormSetmodified_objects changecountrrI change_msgrOr9rrrJrJrKr7s                              zModelAdmin.changelist_viewcCst|||jS)zw Hook for customizing the delete process for the delete view and the "delete selected" action. )rrx)r\objsrrJrJrKr1szModelAdmin.get_deleted_objectscCsFtjt|jd||||WdS1swYdSrU)r#rVr"rWr| _delete_view)r\rrrZrJrJrKr:8s $zModelAdmin.delete_viewcCs||jj}|j}|jt|jt}|r |||s td|| |t ||}| ||s1t |dur<| |||S||g|\}} } } |jrw| sw| rPt t|} |rZt|n|jj} || }|||| |||||| |St|j}| s| rtdd|i}ntd}i|j||d|||t| | | ||||t|jvpt|jv|d |pi}|||S)z'The 'delete' admin view for this model.r\NzCannot delete %(name)srvz Are you sure?) r^r_ object_namerdeleted_objects model_count perms_lacking protectedrrrrar)r|rrrrzrrrrrrrrrrTrrrrrrrrErrrxrirXrcrrrH)r\rrrZrrrrIrr perms_neededrrCr$rDrr^rrJrJrKr=sX         zModelAdmin._delete_viewc Csddlm}|j}||t|}|dur|||j|S|||s%t|j}|j }|j j t|t |d d} i|j|td|d| tt|j||||d|p\i} |jj|_t||jpsd||jfd |d g| S) z(The 'history' admin view for this model.r)rN)r content_type action_timezChange history: %s)r^r_ action_listrrrrzadmin/%s/%s/object_history.htmlzadmin/%s/object_history.htmlzadmin/object_history.html)rrr|rrrrTrrrrrGrrLselect_relatedrrxrirrr7rrrvrr1object_history_templater6) r\rrrZrr|rIrrrrrJrJrKr9xsH         zModelAdmin.history_viewcs(g}g}i}|g}|r|||j|D]z\}|} || dd|| <|| dks/| s7d| || f} || |d} |jdkrU| |j|j d|jvd|d i| } fdd } ||ri|nd st | j D]\} }| ||| | r}qqi|_ |j|_qq|| |q||fS) z9Helper function to generate formsets for add/change_view.rrBz%s-%s)r]rvrrr)r?files save_as_newcs ||od|j||jvS)z0Return whether or not the user deleted the form.z {}-{}-DELETE)rrGrvr)rrIrr0r rJrKuser_deleted_forms z6ModelAdmin._create_formsets..user_deleted_formNrJ)rrwrrzrrererr_rfr~ enumerate initial_forms_errorsrQr;)r\rrIrrr+prefixesget_formsets_argsrrvformset_paramsrrr0rrJrrKrgs@       zModelAdmin._create_formsetsrYNF)rT)F)FFrN)NrN)rN)orSrTrUr rkrlrrrhrirjrrrrrr rxrrrrrrF%delete_selected_confirmation_templaterrrr ActionFormr9rrrr rZrir%r-r>propertyr?rOrPrrRrarmrrrtrurwr|rrrrr6rb staticmethodrrrrdr!BLANK_CHOICE_DASHrrrrcrergrfrrrrINFOrrrrrrrr r&r*r-rr)rBrErHrOrRrTcsrf_protect_mr[rXr8r;rwrzr7rr:rr9rg __classcell__rJrJr)rKr$'s     0         4   /MK C)   r    ;)r$cseZdZdZdZdZeZdZdZ dZ dZ dZ dZ dZdZeZdZfddZedd Zd d d Zd d d Zd ddZd ddZd ddZfddZddZfddZd fdd Zd fdd Zd fdd Z Z!S)!InlineModelAdminz Options for inline editing of ``model`` instances. Provide ``fk_name`` to specify the attribute name of the ``ForeignKey`` from ``model`` to its parent. This is required if ``model`` has more than one ``ForeignKey`` to its parent. NTFcsb||_||_|jj|_||j|_t|j dur"|jjj |_ |j dur/|jjj |_ dSdSrY) rx parent_modelr|rr is_registeredhas_registered_modelr(rirr)r\rrxr)rJrKris     zInlineModelAdmin.__init__cCsftjrdnd}d|ddg}|js|jr|ddg|jr(d|jvr(|d tjd d |Dd S) Nrr@rArBz inlines.jsz SelectBox.jszSelectFilter2.jscollapsez collapse.jscSrCrDrJrErJrJrKrGrHz*InlineModelAdmin.media..rI) rrKrrrWclassesrrrLrMrJrJrKrOs  zInlineModelAdmin.mediacKr)z6Hook for customizing the number of extra inline forms.)rNr\rrIr]rJrJrK get_extrarzInlineModelAdmin.get_extracKr)z4Hook for customizing the min number of inline forms.)min_numrrJrJrK get_min_numrzInlineModelAdmin.get_min_numcKr)z:Hook for customizing the max number of extra inline forms.)r*rrJrJrK get_max_numrzInlineModelAdmin.get_max_numc sd|vr |d}nt|||}|||}|durgnt|}|||||durBt|jdrB|jj j rB||jj j |pEd}|j oN| ||}|j|j |j||t|j|d|j||fi||j||fi||j||fi||d |}|d} |r|||nd|r|||ndGfdd d | } | |d<|ddurt|dstj|d<t|j|jfi|S) zCReturn a BaseInlineFormSet class for use in admin add/change views.rNrrT) rrfk_namerrrUrNrr* can_deleterTcs4eZdZddZfddZfddZZS)z>InlineModelAdmin.get_formset..DeleteProtectedModelFormcSs|jtdrUt|jj}t|d}|jj j rdS| |jg|j rWg}|j D]}| td|jj|dq)|jjjj|jt|tdd}td}t|d |d dSdS) z We don't validate the 'DELETE' field itself because on templates it's not rendered using the field information, but just using a generic "deletion_field" of the InlineModelAdmin. FrNz%(class_name)s %(instance)s) class_namer]and)rr]r zxDeleting %(class_name)s %(instance)s would require deleting the following protected related objects: %(related_objects)sdeleting_protected)codeparams)r;rzr%r"rWrr|rr]_stateaddingcollectrrrrr9r)r\r collectorrprrrJrJrKhand_clean_DELETE+s.     zPInlineModelAdmin.get_formset..DeleteProtectedModelForm.hand_clean_DELETEcst}||SrY)r(r:r)r\resultr)rJrKr:Ks zGInlineModelAdmin.get_formset..DeleteProtectedModelForm.is_validcs.s |jjjs dSs|jjjrdStSr)r]rrr(rr)rscan_add can_changerJrKrPs  zJInlineModelAdmin.get_formset..DeleteProtectedModelForm.has_changed)rSrTrUrr:rrrJrrr)rKDeleteProtectedModelForm)s r)rVrrrrrWrrrrrrrrrrrrrrr~r}r)rrZr(rr|) r\rrIr]rr[rrr]base_model_formrrJrrKrvs>    / zInlineModelAdmin.get_formsetcCs|j||ddjSrQ)rvrrrJrJrKr_sz)InlineModelAdmin._get_form_for_get_fieldscs"t|}||s|}|SrY)r(rrnonerr)rJrKrbs  zInlineModelAdmin.get_querysetcsL|jjD]}|jr|jj|jkr|jjjnqtfdd|DS)a1 This method is called only when the ModelAdmin's model is for an ManyToManyField's implicit through model (if self.opts.auto_created). Return True if the user has any of the given permissions ('add', 'change', etc.) for the model that points to the through model. c3s,|]}jdjt|fVqdS)rN)rrrr)rpermrrrJrKrus  zCInlineModelAdmin._has_any_perms_for_target_model..)rrr{r|rrr)r\rpermsrrJrrK_has_any_perms_for_target_modelhs  z0InlineModelAdmin._has_any_perms_for_target_modelc"|jjr ||dgSt|SNr)rrrr(r}rr)rJrKr}zs z#InlineModelAdmin.has_add_permissioncrr)rrrr(r~rr)rJrKr~s z&InlineModelAdmin.has_change_permissioncs$|jjr ||dgSt||Sr)rrrr(rrr)rJrKrsz&InlineModelAdmin.has_delete_permissioncs$|jjr ||ddgSt|S)Nrr)rrrr(rrr)rJrKrs z$InlineModelAdmin.has_view_permissionrY)"rSrTrUr r|rr'rrNrr*templaterrrshow_change_linkr rZrrirrOrrrrvrrrr}r~rrrrJrJr)rKrs:      Y   rc@eZdZdZdS) StackedInlinezadmin/edit_inline/stacked.htmlNrSrTrUrrJrJrJrKrrc@r) TabularInlinezadmin/edit_inline/tabular.htmlNrrJrJrJrKrrr)r_rrrs functoolsrrr urllib.parserrdjangor django.confrdjango.contribrdjango.contrib.adminr r django.contrib.admin.checksr r r django.contrib.admin.decoratorsrdjango.contrib.admin.exceptionsr,django.contrib.admin.templatetags.admin_urlsrdjango.contrib.admin.utilsrrrrrrrrdjango.contrib.admin.widgetsrrdjango.contrib.authrdjango.core.exceptionsrrrrdjango.core.paginatorr django.dbr!r"r#django.db.models.constantsr$django.forms.formsetsr%r&django.forms.modelsr'r(r)r*r+django.forms.widgetsr,r- django.httpr.django.http.responser/django.template.responser0r1r5r2django.utils.decoratorsr3django.utils.htmlr4django.utils.httpr5django.utils.safestringr6django.utils.textr7r8r9r:r;django.utils.translationr<rr=django.views.decorators.csrfr>django.views.genericr?rr HORIZONTALrNrLrP ExceptionrR DateTimeFieldSplitDateTimeFieldAdminSplitDateTime DateFieldAdminDateWidget TimeFieldAdminTimeWidget TextFieldAdminTextareaWidgetURLFieldAdminURLFieldWidget IntegerFieldAdminIntegerFieldWidgetBigIntegerFieldAdminBigIntegerFieldWidget CharFieldAdminTextInputWidget ImageFieldAdminFileWidget FileField EmailFieldAdminEmailInputWidget UUIDFieldAdminUUIDInputWidgetrarMediaDefiningClassrXr$rrrrJrJrJrKs       ,                       F3I