
    恕f9                       d dl Z d dlZd dlZd dlZd dlZd dlmZ d dlZd dlm	Z	 d dl
mZmZmZmZmZmZmZmZmZ 	 d dlZd dlmZ d dlmZ d dlmZmZ d dlmZmZ d d	l m!Z!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.m/Z/m0Z0m1Z1 d dl2m3Z3 d dl4m5Z5 d dl6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z<m=Z= ddl>m?Z?m@Z@ ddlAmBZB  ej                  d      ZD ej                  d      ZE G d deF      ZG G d deF      ZH G d de!e,      ZIy# e$ r dZY w xY w)    N)ceil)secure_filename)	current_apprequestredirectflashabortjsonResponseget_flashed_messagesstream_with_context)HiddenField)UnboundField)ValidationErrorInputRequired)gettextngettext)BaseViewexpose)BaseFormFormOptsrules)filterstypefmttemplate)ActionsMixin)get_form_datavalidate_form_on_submitget_redirect_targetflash_errorsrec_getattr)ObsoleteAttr)	iteritems
itervaluesOrderedDict
as_unicode
csv_encode	text_typepass_context   )prettify_nameget_mdict_item_or_list)AjaxModelLoaderz
[^a-z0-9 ]z +c                   "    e Zd ZdZ	 	 ddZd Zy)ViewArgsz"
        List view arguments.
    Nc                     || _         || _        || _        t        |      | _        || _        || _        | j
                  sd | _        |xs
 t               | _        y N)	page	page_sizesortbool	sort_descsearchr   dict
extra_args)selfr3   r4   r5   r7   r8   r   r:   s           U/var/www/feuerwehr-webapp/venv/lib/python3.12/site-packages/flask_admin/model/base.py__init__zViewArgs.__init__-   sL    	"	i{{DK$.    c                    | j                   rt        | j                         }nd }|j                  d| j                         |j                  d| j                         |j                  d| j
                         |j                  d| j                         |j                  d| j                         |j                  d|       |j                  dt        | j                               t        di |S )	Nr3   r4   r5   r7   r8   r   r:    )r   list
setdefaultr3   r4   r5   r7   r8   r9   r:   r0   )r;   kwargsflts      r<   clonezViewArgs.clone;   s    <<t||$CC&$)),+t~~6&$)),+t~~6(DKK0)S),T__(=>!&!!r>   )NNNNNNN)__name__
__module____qualname____doc__r=   rE   r@   r>   r<   r0   r0   )   s     HL7;/"r>   r0   c                   $    e Zd Zd Zd Zd Zd Zy)FilterGroupc                      || _         g | _        y r2   )labelr   )r;   rM   s     r<   r=   zFilterGroup.__init__M   s    
r>   c                 :    | j                   j                  |       y r2   )r   appendr;   filters     r<   rO   zFilterGroup.appendQ   s    F#r>   c           	         g }| j                   D ]Z  }t        |      }t        |d         |d<   |d   }|r#|D cg c]  \  }}|t        |      f c}}|d<    |j                  |       \ t        | j
                        |fS c c}}w )N	operationoptions)r   r9   r'   r)   rO   rM   )r;   r   itemcopyrT   kvs          r<   non_lazyzFilterGroup.non_lazyT   s    LL 	!D:D *4+< =D9oGAH"IAAy|#4"IYGNN4 	! $**%w.. #Js   Bc                 ,    t        | j                        S r2   )iterr   r;   s    r<   __iter__zFilterGroup.__iter__`   s    DLL!!r>   N)rF   rG   rH   r=   rO   rY   r]   r@   r>   r<   rK   rK   L   s    $
/"r>   rK   c                   B    e Zd ZdZdZ	 dZ	 dZ	 dZ	 dZ	 dZ		 dZ
	 dZ	 dZ	 dZ	 d	Z	 d
Z	 dZ	 dZ	 dZ	  eddd      Z	  eddd      Z	 dZ	 dZ	 dZ	 dZ	  edd e             Z	 dZ	 dZ	  eddd      Z	 dZ	 dZ 	  eddd      Z!	 dZ"	  eddd      Z#	 dZ$	  eddd      Z%	 dZ&	 dZ'	 dZ(	 dZ)	  eddd      Z*	 dZ+	 dZ,	 dZ-	 dZ.	 e/Z0	 dZ1	 dZ2	  eddd      Z3	 dZ4	 dZ5	 dZ6	 dZ7	 dZ8	 dZ9	 dZ:	  eddg       Z;	 d Z<	 d!gZ=	 d"Z>	 dZ?	 	 	 d fd#	Z@ fd$ZAd% ZBd& ZCd' ZDd( ZEd) ZFd* ZGd+ ZHd, ZId- ZJd. ZKd/ ZLd0 ZMd1 ZNd2 ZOd3 ZPd4 ZQd5 ZRd6 ZSd7 ZTd8 ZUd9 ZVd: ZWd; ZXdd<ZYd= ZZd> Z[d? Z\d@ Z]dA Z^dB Z_ddCZ`ddDZadE ZbddFZcddGZddH ZeddIZfdJ ZgdK ZhddLZiddMZjdN ZkdO ZldP ZmdQ ZndR ZodS Zp	 ddTZqdU ZrdV ZsdW ZtdX ZudY ZvdZ Zwd[ Zxd\ Zyd] Zzd^ Z{d_ Z|d` Z}da Z~db Zdc Zdd Zde Zdf Zdg Zdh Zdi Zedj        Zedk        Zdl ZddmZdn Zdo Z edp      dq        Z edrdst      du        Z edvdst      dw        Z edx      dy        Z edzd{t      d|        Z ed}d{t      d~        Zd Z ed      d        Zd Zd Z ed      d        Z edd{t      d        Z xZS )BaseModelViewan  
        Base model view.

        This view does not make any assumptions on how models are stored or managed, but expects the following:

            1. The provided model is an object
            2. The model contains properties
            3. Each model contains an attribute which uniquely identifies it (i.e. a primary key for a database model)
            4. It is possible to retrieve a list of sorted models with pagination applied from a data source
            5. You can get one model by its identifier from the data source

        Essentially, if you want to support a new data store, all you have to do is:

            1. Derive from the `BaseModelView` class
            2. Implement various data-related methods (`get_list`, `get_one`, `create_model`, etc)
            3. Implement automatic form generation from the model representation (`scaffold_form`)
    TFzadmin/model/list.htmlzadmin/model/edit.htmlzadmin/model/create.htmlzadmin/model/details.htmlzadmin/model/modals/edit.htmlzadmin/model/modals/create.htmlzadmin/model/modals/details.htmlcolumn_listlist_columnsNcolumn_exclude_listexcluded_list_columnscolumn_formatterslist_formatterscolumn_type_formatterslist_type_formatterscolumn_labelsrename_columnscolumn_sortable_listsortable_columnscolumn_searchable_listsearchable_columnscolumn_display_pklist_display_pkform_excluded_columnsexcluded_form_columnsaction_disallowed_listdisallowed_actionsr   csv   c
           
          || _         |d| j                  |j                        z  }t        t        |   ||||||||	       | j                          | j                          y)aa  
            Constructor.

            :param model:
                Model class
            :param name:
                View name. If not provided, will use the model class name
            :param category:
                Optional category name, for grouping views in the menu
            :param endpoint:
                Base endpoint. If not provided, will use the model name.
            :param url:
                Base URL. If not provided, will use endpoint as a URL.
            :param menu_class_name:
                Optional class name for the menu item.
            :param menu_icon_type:
                Optional icon. Possible icon types:

                 - `flask_admin.consts.ICON_TYPE_GLYPH` - Bootstrap glyph icon
                 - `flask_admin.consts.ICON_TYPE_FONT_AWESOME` - Font Awesome icon
                 - `flask_admin.consts.ICON_TYPE_IMAGE` - Image relative to Flask static directory
                 - `flask_admin.consts.ICON_TYPE_IMAGE_URL` - Image with full URL
            :param menu_icon_value:
                Icon glyph name or URL, depending on `menu_icon_type` setting
        Nz%s)menu_class_namemenu_icon_typemenu_icon_value)model_prettify_class_namerF   superr_   r=   init_actions_refresh_cache)r;   rz   namecategoryendpointurlstatic_folderrw   rx   ry   	__class__s             r<   r=   zBaseModelView.__init__  sp    8 
 <$33ENNCCDmT+D(Hc=<K;I<K 	, 	M 	 	r>   c                 v    |rt         t        |   |      S | j                  j                  j                         S r2   )r|   r_   _get_endpointrz   rF   lower)r;   r   r   s     r<   r   zBaseModelView._get_endpoint5  s1    ;HEEzz""((**r>   c                 N   | j                         | _        | j                  i | _        | j                         | _        | j                         | _        | j                         | _        | j                         | _
        | j                  r| j                         | _        y i | _        y r2   )_process_ajax_references_form_ajax_refsform_widget_argsget_create_form_create_form_classget_edit_form_edit_form_classget_delete_form_delete_form_classget_action_form_action_form_classcolumn_editable_listget_list_form_list_form_classr\   s    r<   _refresh_forms_cachez"BaseModelView._refresh_forms_cache<  s    #<<>  ($&D!"&"6"6"8 $ 2 2 4"&"6"6"8"&"6"6"8 $$$($6$6$8D!(*D%r>   c           	      T   | j                         | _        | j                  rt               | _        i | _        t        | j                        D ]  \  }}t        |j                        }|| j                  vr"t        |j                        | j                  |<   | j                  |   j                  || j                  ||      |j                         |j                  |       xs d |j                  d       ||f| j                  | j                  ||      <    y d | _        d | _        y )N)indexargrS   rT   type)get_filters_filtersr&   _filter_groups_filter_args	enumerater'   r   rK   rO   get_filter_argrS   get_options	data_type)r;   irD   keys       r<   _refresh_filters_cachez$BaseModelView._refresh_filters_cacheN  s   ((*=="--D "D#DMM2 J3 *d111/:388/DD'',##C(//..q#6!$"t4<MM1  CDS!!$"5"5a"=>J #'D $Dr>   c                    | j                   r&t        j                  | | j                         | _        nd | _        | j                  r&t        j                  | | j                        | _        nd | _        | j                  rHt        j                  | | j                        }| j                  s|| _        | j
                  s|| _        y y y r2   )form_create_rulesr   RuleSet_form_create_rulesform_edit_rules_form_edit_rules
form_rules)r;   r   s     r<   _refresh_form_rules_cachez'BaseModelView._refresh_form_rules_cachef  s    !!&+mmD$:P:P&QD#&*D#$)MM$8L8L$MD!$(D!??tT__=J***4'(((2% ) r>   c           
         | j                         | _        | j                         | _        | j                  r| j                         | _        | j                         | _        | j                  i | _	        | j                          | j                         | _        | j                  rGt        | j                  j                         D cg c]  \  }}|t        |      f c}}      | _        nt               x| _        | _        | j"                  | j$                  | _        | j&                  | j$                  | _        | j(                  t        t*        j,                        | _        | j.                  t        t*        j0                        | _        | j2                  t        t*        j4                        | _        | j6                  t               | _        | j9                          | j;                          | j=                  | j>                  | j@                         | j=                  | jB                  | jD                         yc c}}w )z7
            Refresh various cached variables.
        N)#get_list_columns_list_columnsget_sortable_columns_sortable_columnscan_view_detailsget_details_columns_details_columnsget_export_columns_export_columnsrh   r   init_search_search_supportedcolumn_choicesr9   items_column_choices_mapcolumn_formatters_exportrd   column_formatters_detailrf   r   BASE_FORMATTERScolumn_type_formatters_exportEXPORT_FORMATTERScolumn_type_formatters_detailDETAIL_FORMATTERScolumn_descriptionsr   r   _validate_form_classr   r   r   r   )r;   columnchoicess      r<   r~   zBaseModelView._refresh_cachez  s   
 "224!%!:!:!<   $($<$<$>D!  $668 %!#D 	!!# "&!1!1!3 '+'+':':'@'@'B-#FG g'- (D$
 >BVCD$": ((0,0,B,BD)((0,0,B,BD) &&.*.w/F/F*GD'--515g6O6O1PD.--515g6O6O1PD.##+'+vD$ 	##% 	&&( 	!!$"7"79N9NO!!$"9"94;R;RSG-s   I
c                     t               )z:
            Return PK value from a model object.
        NotImplementedErrorr;   rz   s     r<   get_pk_valuezBaseModelView.get_pk_value       "##r>   c                     t        d      )a  
            Return list of the model field names. Must be implemented in
            the child class.

            Expected return format is list of tuples with field name and
            display text. For example::

                ['name', 'first_name', 'last_name']
        z-Please implement scaffold_list_columns methodr   r\   s    r<   scaffold_list_columnsz#BaseModelView.scaffold_list_columns  s     ""QRRr>   c                 v    | j                   r|| j                   v r| j                   |   S | j                  |      S )zw
            Return a human-readable column name.

            :param field:
                Model field name.
        )rh   _prettify_name)r;   fields     r<   get_column_namezBaseModelView.get_column_name  s<     %4+=+="=%%e,,&&u--r>   c                    g }| j                   rS| j                  r$|j                  t        j                                n#|j                  t        j
                                | j                  rS| j                  r$|j                  t        j                                n#|j                  t        j                                | j                  r#|j                  t        j                                || j                  xs g z   S )z
            Return list of row action objects, each is instance of
            :class:`~flask_admin.model.template.BaseListRowAction`
        )r   details_modalrO   r   ViewPopupRowActionViewRowActioncan_edit
edit_modalEditPopupRowActionEditRowAction
can_deleteDeleteRowActioncolumn_extra_row_actions)r;   actionss     r<   get_list_row_actionsz"BaseModelView.get_list_row_actions  s    
   !!x::<=x5578==x::<=x5578??NN83356$77=2>>r>   c                     |r|D cg c]	  }||vs| }}|D cg c]  }|| j                  |      f c}S c c}w c c}w )a  
            Returns a list of tuples with the model field name and formatted
            field name.

            :param only_columns:
                List of columns to include in the results. If not set,
                `scaffold_list_columns` will generate the list from the model.
            :param excluded_columns:
                List of columns to exclude from the results if `only_columns`
                is not set.
        )r   )r;   only_columnsexcluded_columnscs       r<   get_column_nameszBaseModelView.get_column_names  sL     '3Q!q@P7PAQLQ6BCD((+,CC RCs   	88=c                 t    | j                  | j                  xs | j                         | j                        S )a-  
            Uses `get_column_names` to get a list of tuples with the model
            field name and formatted name for the columns in `column_list`
            and not in `column_exclude_list`. If `column_list` is not set,
            the columns from `scaffold_list_columns` will be used.
        r   r   )r   r`   r   rb   r\   s    r<   r   zBaseModelView.get_list_columns  s<     $$))IT-G-G-I!55 % 
 	
r>   c                     	 | j                   xs | j                         }| j	                  || j
                        S # t        $ r t        d      w xY w)aE  
            Uses `get_column_names` to get a list of tuples with the model
            field name and formatted name for the columns in `column_details_list`
            and not in `column_details_exclude_list`. If `column_details_list`
            is not set, the columns from `scaffold_list_columns` will be used.
        z!Please define column_details_listr   )column_details_listr   r   	Exceptionr   column_details_exclude_listr;   r   s     r<   r   z!BaseModelView.get_details_columns  sf    	A33St7Q7Q7SL $$%!== % 
 	
 # 	A?@@	As	   = Ac                     | j                   xs | j                  xs | j                         }| j                  || j                        S )a  
            Uses `get_column_names` to get a list of tuples with the model
            field name and formatted name for the columns in `column_export_list`
            and not in `column_export_exclude_list`. If `column_export_list` is
            not set, it will attempt to use the columns from `column_list`
            or finally the columns from `scaffold_list_columns` will be used.
        r   )column_export_listr`   r   r   column_export_exclude_listr   s     r<   r   z BaseModelView.get_export_columns   sV     // 543C3C 5224 	 $$%!<< % 
 	
r>   c                     t        d      )z
            Returns dictionary of sortable columns. Must be implemented in
            the child class.

            Expected return format is a dictionary, where keys are field names and
            values are property names.
        z1Please implement scaffold_sortable_columns methodr   r\   s    r<   scaffold_sortable_columnsz'BaseModelView.scaffold_sortable_columns0  s     ""UVVr>   c                     | j                   | j                         xs
 t               S t               }| j                   D ]#  }t        |t              r|d   ||d   <   |||<   % |S )a2  
            Returns a dictionary of the sortable columns. Key is a model
            field name and value is sort column (for example - attribute).

            If `column_sortable_list` is set, will use it. Otherwise, will call
            `scaffold_sortable_columns` to get them from the model.
        r+   r   )rj   r   r9   
isinstancetuple)r;   resultr   s      r<   r   z"BaseModelView.get_sortable_columns:  sm     $$,113=tv=VF.. "a'#$Q4F1Q4L !F1I	" Mr>   c                      y)z
            Initialize search. If data provider does not support search,
            `init_search` will return `False`.
        Fr@   r\   s    r<   r   zBaseModelView.init_searchO  s    
 r>   c                      y)z5
            Return search placeholder text.
        Nr@   r\   s    r<   search_placeholderz BaseModelView.search_placeholderV  s     r>   c                      y)z{
            Generate filter object for the given name

            :param name:
                Name of the field
        Nr@   r;   r   s     r<   scaffold_filterszBaseModelView.scaffold_filters]  s     r>   c                 6    t        |t        j                        S )z
            Verify that the provided filter object is valid.

            Override in model backend implementation to verify if
            the provided filter type is allowed.

            :param filter:
                Filter object to verify.
        )r   r   
BaseFilterrP   s     r<   is_valid_filterzBaseModelView.is_valid_filterf  s     &'"4"455r>   c                     |S )z
            Postprocess (add joins, etc) for a filter.

            :param filter:
                Filter object to postprocess
        r@   rP   s     r<   handle_filterzBaseModelView.handle_filterr  s	     r>   c                    | j                   ryg }| j                   D ]f  }| j                  |      r!|j                  | j                  |             5| j	                  |      }|r|j                  |       Zt        d|z         |S y)z
            Return a list of filter objects.

            If your model backend implementation does not support filters,
            override this method and return `None`.
        zUnsupported filter type %sN)column_filtersr   rO   r  r   extendr   )r;   
collectionnrD   s       r<   r   zBaseModelView.get_filters{  s     J(( J''*%%d&8&8&;<//2C"))#.'(Dq(HIIJ r>   c                 :   | j                   rv|j                         }	 |j                  d   }|j                  dt        |      j                         }t        j                  d|      }t        j                  d|      }|S t        |      S # t        $ r Y lw xY w)a4  
            Given a filter `flt`, return a unique name for that filter in
            this view.

            Does not include the `flt[n]_` portion of the filter name.

            :param index:
                Filter index in _filters array
            :param flt:
                Filter instance
        r     _)named_filter_urlsrS   _argsAttributeErrorr   r'   r   filter_char_resubfilter_compact_restr)r;   r   rD   rS   r   s        r<   r   zBaseModelView.get_filter_arg  s     !!I%OOA.	  #xxI)>?FFHD!%%b$/D$((d3DKu: " s   B 	BBc                     | j                   r>t               }t        | j                         D ]  }|j                         \  }}|||<    |S y)z@
            Returns non-lazy version of filter strings
        N)r   r&   r%   rY   )r;   resultsgroupr   r   s        r<   _get_filter_groupsz BaseModelView._get_filter_groups  sQ     !mG#D$7$78 %"^^-
U$% Nr>   c                     t        d      )z
            Create `form.BaseForm` inherited class from the model. Must be
            implemented in the child class.
        z%Please implement scaffold_form methodr   r\   s    r<   scaffold_formzBaseModelView.scaffold_form  s    
 ""IJJr>   c                     t        d      )a  
            Create form for the `index_view` using only the columns from
            `self.column_editable_list`.

            :param widget:
                WTForms widget class. Defaults to `XEditableWidget`.
            :param validators:
                `form_args` dict with only validators
                {'name': {'validators': [DataRequired()]}}

            Must be implemented in the child class.
        z*Please implement scaffold_list_form methodr   )r;   widget
validatorss      r<   scaffold_list_formz BaseModelView.scaffold_list_form  s     ""NOOr>   c                 R    | j                   | j                   S | j                         S )z
            Get form class.

            If ``self.form`` is set, will return it and will call
            ``self.scaffold_form`` otherwise.

            Override to implement customized behavior.
        )formr  r\   s    r<   get_formzBaseModelView.get_form  s'     99 99!!##r>   c                     | j                   r&t        d t        | j                         D              }nd}| j                  |      S )aS  
            Get form class for the editable list view.

            Uses only validators from `form_args` to build the form class.

            Allows overriding the editable list view field/widget. For example::

                from flask_admin.model.widgets import XEditableWidget

                class CustomWidget(XEditableWidget):
                    def get_kwargs(self, subfield, kwargs):
                        if subfield.type == 'TextAreaField':
                            kwargs['data-type'] = 'textarea'
                            kwargs['data-rows'] = '20'
                        # elif: kwargs for other fields

                        return kwargs

                class MyModelView(BaseModelView):
                    def get_list_form(self):
                        return self.scaffold_list_form(widget=CustomWidget)
        c              3   V   K   | ]!  \  }}|j                  d       r|d |d    if # yw)r  N)get).0r   values      r<   	<genexpr>z.BaseModelView.get_list_form.<locals>.<genexpr>  s7      C99\* |U<%89:s   ')Nr  )	form_argsr9   r$   r  )r;   r  s     r<   r   zBaseModelView.get_list_form  sF    . >> "+DNN"; J J&&*&==r>   c                 "    | j                         S )zx
            Create form class for model creation view.

            Override to implement customized behavior.
        r  r\   s    r<   r   zBaseModelView.get_create_form       }}r>   c                 "    | j                         S )zw
            Create form class for model editing view.

            Override to implement customized behavior.
        r(  r\   s    r<   r   zBaseModelView.get_edit_form  r)  r>   c                 0     G d d| j                         }|S )zv
            Create form class for model delete view.

            Override to implement customized behavior.
        c                   8    e Zd Z e e       g      Z e       Zy)1BaseModelView.get_delete_form.<locals>.DeleteFormr%  N)rF   rG   rH   r   r   idr   r@   r>   r<   
DeleteFormr-    s    (9:B-Cr>   r/  form_base_class)r;   r/  s     r<   r   zBaseModelView.get_delete_form  s    	 -- 	  r>   c                 0     G d d| j                         }|S )zs
            Create form class for a model action.

            Override to implement customized behavior.
        c                   (    e Zd Z e       Z e       Zy)1BaseModelView.get_action_form.<locals>.ActionFormN)rF   rG   rH   r   actionr   r@   r>   r<   
ActionFormr4  '  s     ]F-Cr>   r6  r0  )r;   r6  s     r<   r   zBaseModelView.get_action_form!  s    	 -- 	 
 r>   c                 8    | j                  t               |      S )zx
            Instantiate model creation form and return it.

            Override to implement custom behavior.
        obj)r   r   r;   r9  s     r<   create_formzBaseModelView.create_form.       &&}C&@@r>   c                 8    | j                  t               |      S )zw
            Instantiate model editing form and return it.

            Override to implement custom behavior.
        r8  )r   r   r:  s     r<   	edit_formzBaseModelView.edit_form6       $$]_#$>>r>   c                     t         j                  r| j                  t         j                        S t         j                  r| j                  t         j                        S | j                         S )a  
            Instantiate model delete form and return it.

            Override to implement custom behavior.

            The delete form originally used a GET request, so delete_form
            accepts both GET and POST request for backwards compatibility.
        )r   r  r   argsr\   s    r<   delete_formzBaseModelView.delete_form>  sK     <<**7<<88\\**7<<88**,,r>   c                 8    | j                  t               |      S )z
            Instantiate model editing form for list view and return it.

            Override to implement custom behavior.
        r8  )r   r   r:  s     r<   	list_formzBaseModelView.list_formO  r?  r>   c                 8    | j                  t               |      S )zv
            Instantiate model action form and return it.

            Override to implement custom behavior.
        r8  )r   r   r:  s     r<   action_formzBaseModelView.action_formW  r<  r>   c                     t        |      S )zm
            Validate the form on submit.

            :param form:
                Form to validate
        )r   r;   r  s     r<   validate_formzBaseModelView.validate_form_  s     't,,r>   c                 <    t               xs | j                  d      S )a4  
            Return url where user is redirected after successful form save.

            :param model:
                Saved object
            :param is_created:
                Whether new object was created or existing one was updated

            For example, redirect use to object details view after form save::

                class MyModelView(ModelView):
                    can_view_details = True

                    def get_save_return_url(self, model, is_created):
                        return self.get_url('.details_view', id=model.id)

        .index_view)r   get_url)r;   rz   
is_createds      r<   get_save_return_urlz!BaseModelView.get_save_return_urlh  s    $ #$C](CCr>   c                     g }|r=|j                   }|D ],  }|j                  |vs|j                  |j                         . |S r2   )visible_fieldsr   rO   )r;   rulesetr  missing_fieldsrP  r   s         r<   _get_ruleset_missing_fieldsz)BaseModelView._get_ruleset_missing_fields|  sJ    $33N 6::^3"))%**56 r>   c                 .    t        j                  |       y r2   )warningswarn)r;   texts     r<   _show_missing_fields_warningz*BaseModelView._show_missing_fields_warning  s    dr>   c                 T   g }t        |j                        D ]'  \  }}t        |t              s|j	                  |       ) g }|r)|j
                  }|D ]  }	|	|vs|j	                  |	        |r#| j                  ddj                  |      z         |r| j                  ||       y y )NFields missing from ruleset: %s,)	r$   __dict__r   r   rO   rP  rX  join_remove_fields_from_form_class)
r;   rQ  
form_classremove_missingform_fieldsr   r9  rR  rP  
field_names
             r<   r   z"BaseModelView._validate_form_class  s    ":#6#67 	)ID##|,""4(	) $33N) 6
^3"))*56 --.OSVS[S[\jSk.lm//
K r>   c                     | j                  ||      }|r#| j                  ddj                  |      z         |r| j                  ||       y y )NrQ  r  rZ  r[  )rS  rX  r]  !_remove_fields_from_form_instance)r;   rQ  r  r`  rR  s        r<   _validate_form_instancez%BaseModelView._validate_form_instance  sT    99'PT9U--.OSVS[S[\jSk.lm22>4H r>   c                 4    |D ]  }|j                  |        y r2   )__delitem__)r;   field_namesr  rb  s       r<   re  z/BaseModelView._remove_fields_from_form_instance  s    % 	)JZ(	)r>   c                 *    |D ]  }t        ||        y r2   )delattr)r;   ri  r_  rb  s       r<   r^  z,BaseModelView._remove_fields_from_form_class  s    % 	,JJ
+	,r>   c                 H    |j                         d | j                  D        v S )z
            Verify if column is sortable.

            Not case-sensitive.

            :param name:
                Column name.
        c              3   <   K   | ]  }|j                           y wr2   )r   )r"  xs     r<   r$  z,BaseModelView.is_sortable.<locals>.<genexpr>  s     Ja	Js   )r   r   r   s     r<   is_sortablezBaseModelView.is_sortable  s!     zz|J43I3IJJJr>   c                 :    || j                   v xr | j                  S )zj
            Verify if column is editable.

            :param name:
                Column name.
        )r   r   r   s     r<   is_editablezBaseModelView.is_editable  s     t000BT]]Br>   c                 `    ||dk  s|t        | j                        k\  ry| j                  |   S )z,
            Return column index by
        Nr   )lenr   )r;   idxs     r<   _get_column_by_idxz BaseModelView._get_column_by_idx  s5     ;#'SC0B0B,C%C!!#&&r>   c                     | j                   r\t        | j                   t              r| j                   S t        | j                   t              r| j                   gS | j                   dfgS y)z/
            Return default sort order
        FN)column_default_sortr   rA   r   r\   s    r<   _get_default_orderz BaseModelView._get_default_order  s_     ##$22D9///$22E:00111159::r>   c                     t        d      )al  
            Return a paginated and sorted list of models from the data source.

            Must be implemented in the child class.

            :param page:
                Page number, 0 based. Can be set to None if it is first page.
            :param sort_field:
                Sort column name or None.
            :param sort_desc:
                If set to True, sorting is in descending order.
            :param search:
                Search query
            :param filters:
                List of filter tuples. First value in a tuple is a search
                index, second value is a search value.
            :param page_size:
                Number of results. Defaults to ModelView's page_size. Can be
                overriden to change the page_size limit. Removing the page_size
                limit requires setting page_size to 0 or False.
        z Please implement get_list methodr   )r;   r3   
sort_fieldr7   r8   r   r4   s          r<   get_listzBaseModelView.get_list  s    . ""DEEr>   c                     t        d      )z
            Return one model by its id.

            Must be implemented in the child class.

            :param id:
                Model id
        zPlease implement get_one methodr   )r;   r.  s     r<   get_onezBaseModelView.get_one  s     ""CDDr>   c                     t        |t              rt        t        |      d       yt        j
                  j                  d      r | j                  r y)NerrorTADMIN_RAISE_ON_VIEW_EXCEPTIONF)r   r   r   r'   r   configr!  _debug)r;   excs     r<   handle_view_exceptionz#BaseModelView.handle_view_exception  sB    c?+*S/7+!!"AB;;r>   c                      y)a  
            Perform some actions before a model is created or updated.

            Called from create_model and update_model in the same transaction
            (if it has any meaning for a store backend).

            By default does nothing.

            :param form:
                Form used to create/update model
            :param model:
                Model that will be created/updated
            :param is_created:
                Will be set to True if model was created and to False if edited
        Nr@   r;   r  rz   rM  s       r<   on_model_changezBaseModelView.on_model_change        	r>   c                    	 | j                  |||       y# t        $ ra}t        j                  dt	        |            r7d| j
                  z  }t        j                  |       | j                  ||       n Y d}~yd}~ww xY w)z+
            Compatibility helper.
        z<on_model_change\(\) takes .* 3 .* arguments .* 4 .* given .*zT%s.on_model_change() now accepts third parameter is_created. Please update your codeN)r  	TypeErrorrematchr  rz   rU  rV  )r;   r  rz   rM  emsgs         r<   _on_model_changezBaseModelView._on_model_change  sx    
	  uj9 	xxWY\]^Y_`GJN**Uc"$$T51 2	s    	B AA;;B c                      y)a  
            Perform some actions after a model was created or updated and
            committed to the database.

            Called from create_model after successful database commit.

            By default does nothing.

            :param form:
                Form used to create/update model
            :param model:
                Model that was created/updated
            :param is_created:
                True if model was created, False if model was updated
        Nr@   r  s       r<   after_model_changez BaseModelView.after_model_change-  r  r>   c                      y)z
            Perform some actions before a model is deleted.

            Called from delete_model in the same transaction
            (if it has any meaning for a store backend).

            By default do nothing.
        Nr@   r   s     r<   on_model_deletezBaseModelView.on_model_delete?  s     	r>   c                      y)aW  
            Perform some actions after a model was deleted and
            committed to the database.

            Called from delete_model after successful database commit
            (if it has any meaning for a store backend).

            By default does nothing.

            :param model:
                Model that was deleted
        Nr@   r   s     r<   after_model_deletez BaseModelView.after_model_deleteJ  s     	r>   c                      y)a  
            Perform additional actions to pre-fill the edit form.

            Called from edit_view, if the current action is rendering
            the form rather than receiving client side input, after
            default pre-filling has been performed.

            By default does nothing.

            You only need to override this if you have added custom
            fields that depend on the database contents in a way that
            Flask-admin can't figure out by itself. Fields that were
            added by name of a normal column or relationship should
            work out of the box.

            :param form:
                Form instance
            :param id:
                id of the object that is going to be edited
        Nr@   )r;   r  r.  s      r<   on_form_prefillzBaseModelView.on_form_prefillY  s    * 	r>   c                     t               )z
            Create model from the form.

            Returns the model instance if operation succeeded.

            Must be implemented in the child class.

            :param form:
                Form instance
        r   rH  s     r<   create_modelzBaseModelView.create_modelp       "##r>   c                     t               )a  
            Update model from the form.

            Returns `True` if operation succeeded.

            Must be implemented in the child class.

            :param form:
                Form instance
            :param model:
                Model instance
        r   )r;   r  rz   s      r<   update_modelzBaseModelView.update_model}  s     "##r>   c                     t               )z
            Delete model.

            Returns `True` if operation succeeded.

            Must be implemented in the child class.

            :param model:
                Model instance
        r   r   s     r<   delete_modelzBaseModelView.delete_model  r  r>   c                     t        |      S )z
            Prettify pythonic variable name.

            For example, 'hello_world' will be converted to 'Hello World'

            :param name:
                Name to prettify
        )r,   r   s     r<   r   zBaseModelView._prettify_name  s     T""r>   c                     t        d      S )Nz There are no items in the table.r   r\   s    r<   get_empty_list_messagez$BaseModelView.get_empty_list_message  s    9::r>   c                     t        d|      S )z
        Returns message, which should be printed in case of failed validation.
        :param value: Invalid value
        :param filter: Filter
        :return: string
        zInvalid Filter Value: %(value)s)r#  r  )r;   r#  rQ   s      r<   get_invalid_value_msgz#BaseModelView.get_invalid_value_msg  s     8FFr>   c                    | j                   rg }t        j                  D ]  }|j                  d      sd|vr|dd  j	                  dd      \  }}|| j
                  v sA| j
                  |   \  }}t        j                  |   }|j                  |      r-||t        |j                        |ff} |j                  |       t        | j                  ||      d        t        |d       D 	cg c]  }	|	d   	 c}	S y c c}	w )NrD   r
     r+   r  c                     | d   S )Nr   r@   )r  s    r<   <lambda>z5BaseModelView._get_list_filter_args.<locals>.<lambda>  s
    ! r>   )r   )r   r   rA  
startswithsplitr   validater'   r   rO   r   r  sorted)
r;   r   r   posr   rt  rD   r#  datarX   s
             r<   _get_list_filter_argsz#BaseModelView._get_list_filter_args  s    ==G|| O~~e,c>qr7==a0S$+++#005HC#LL-E||E* #c:chh+?%GH&t,d88DgN%O* #)n"EFQAaDFF Gs   1Dc                 H   t        t        j                  j                  ddt              t        j                  j                  ddt              t        j                  j                  ddt              t        j                  j                  ddt              t        j                  j                  dd      | j                         t        t        j                  j                         D cg c]  \  }}|d	vr|j                  d
      s||f  c}}            S c c}}w )z9
            Return arguments from query string.
        r3   r   r   r4   r5   Ndescr8   )r3   r4   r5   r  r8   rD   )r3   r4   r5   r7   r8   r   r:   )	r0   r   rA  r!  intr  r9   r   r  )r;   rW   rX   s      r<   _get_list_extra_argsz"BaseModelView._get_list_extra_args  s     W\\--fac-B"),,"2"2;"2"L$\\--fd-E"),,"2"264c"2"J&||//$? $ : : <#'/6||/A/A/C)'+q! (YY !U 3 F) $
 
	)s   .#Dc                     i }|rBt        |      D ]4  \  }}|\  }}}d|| j                  || j                  |         fz  }|||<   6 |S )z
            Get active filters as dictionary of URL arguments and values

            :param filters:
                List of filters from ViewArgs object
        zflt%d_%s)r   r   r   )	r;   r   rC   r   pairrt  flt_namer#  r   s	            r<   _get_filterszBaseModelView._get_filters  se     $W- $4'+$Xu At':':3c@R'S#TT#s	$ r>   c                 l   |j                   xs d}|j                  rdnd}t        ||j                  ||j                        }|j                  |j                         |j                  r|j                  |d<   |j                  | j                  |j                                | j                  di |S )z
            Generate page URL with current page, sort column and
            other parameters.

            :param view:
                View name
            :param view_args:
                ViewArgs object with page number, filters, etc.
        Nr+   )r3   r5   r  r8   r4   )rK  )r3   r7   r9   r5   r8   updater:   r4   r  r   rL  )r;   	view_argsr3   r  rC   s        r<   _get_list_urlzBaseModelView._get_list_url  s     ~~%''qT4inn4	HXHXYi**+"+"5"5F;d''	(9(9:;t||4V44r>   c                     || j                   vS )z
            Override this method to allow or disallow actions based
            on some condition.

            The default implementation only checks if the particular action
            is not in `action_disallowed_list`.
        )rr   r   s     r<   is_action_allowedzBaseModelView.is_action_allowed
  s     46666r>   c                     t        ||      S )z@
            Get unformatted field value from the model
        r!   r;   rz   r   s      r<   _get_field_valuezBaseModelView._get_field_value  s     5$''r>   c                    |j                  |      }| || |||      }n| j                  ||      }| j                  j                  |i       }|r|j                  |      xs |S d}	|j                         D ]  \  }
}t	        ||
      s|}	 n |		  |	| ||      }|S |S # t
        $ rU t        j                  |	      }t        |j                        dk(  rt        j                  d|	 d       n  |	| |      }Y |S w xY w)a  
            Returns the value to be displayed.

            :param context:
                :py:class:`jinja2.runtime.Context` if available
            :param model:
                Model instance
            :param name:
                Field name
            :param column_formatters:
                column_formatters to be used.
            :param column_type_formatters:
                column_type_formatters to be used.
        N   z"Please update your type formatter z( to include additional `name` parameter.)r!  r  r   r   r   r  inspectgetfullargspecrs  rA  rU  rV  )r;   contextrz   r   rd   rf   
column_fmtr#  choices_maptype_fmttypeobj	formatterspecs                r<   _get_list_valuezBaseModelView._get_list_value  s-     '**40
!tWeT:E))%6E..224<??5)2U2"8">">"@ 	GY%)$	 . ud3 u  	.--h7tyy>Q&MM$Fxj QI #I J  u-	.s   
B   AC>=C>c                 T    | j                  |||| j                  | j                        S )a  
            Returns the value to be displayed in the list view

            :param context:
                :py:class:`jinja2.runtime.Context`
            :param model:
                Model instance
            :param name:
                Field name
        )r  rd   rf   r;   r  rz   r   s       r<   get_list_valuezBaseModelView.get_list_valueI  s2     ##""''
 	
r>   c                 T    | j                  |||| j                  | j                        S )a  
            Returns the value to be displayed in the detail view

            :param context:
                :py:class:`jinja2.runtime.Context`
            :param model:
                Model instance
            :param name:
                Field name
        )r  r   r   r  s       r<   get_detail_valuezBaseModelView.get_detail_value]  s2     ##))..
 	
r>   c                 T    | j                  d||| j                  | j                        S )z
            Returns the value to be displayed in export.
            Allows export to use different (non HTML) formatters.

            :param model:
                Model instance
            :param name:
                Field name
        N)r  r   r   r  s      r<   get_export_valuezBaseModelView.get_export_valueq  s2     ##))..
 	
r>   c                 T    | j                   dt        j                  d      d|}|S )z6
        :return: The exported csv file name.
        r
  z%Y-%m-%d_%H-%M-%S.)r   timestrftime)r;   export_typefilenames      r<   get_export_namezBaseModelView.get_export_name  s)     "&!%/B!C!,. r>   c                    i }| j                   rrt        | j                         D ]Z  \  }}t        |t              r| j	                  ||      ||<   ,t        |t
              r|||<   Bt        | dt        |      d       |S )z
            Process `form_ajax_refs` and generate model loaders that
            will be used by the `ajax_lookup` view.
        z.form_ajax_refs can not handle z types)form_ajax_refsr$   r   r9   _create_ajax_loaderr.   
ValueErrorr   )r;   r   r   rT   s       r<   r   z&BaseModelView._process_ajax_references  s    
 !*4+>+>!? jggt,#'#;#;D'#JF4L9#*F4L$TXZ^_fZg%hiij r>   c                     t               )zW
            Model backend will override this to implement AJAX model loading.
        r   )r;   r   rT   s      r<   r  z!BaseModelView._create_ajax_loader  r   r>   /c           	           j                   r j                         }nd} j                          j                  j                        }||d   }j
                  xs  j
                  } j                  j                  |j                  j                  j                  |      \  }}i } j                  r+|D ]&  } j                  |      | j                  |      <   ( |#|r!t        t        |t!        |      z              }n|sd}nd} fd}	d+ fd	}
 fd} j#                         \  }}|r j%                         }nd} j'                  j)                  dj                  j                  dd            }  j*                   j,                  fi d	|d
|d|d|d j.                  d j0                  d j                  d j3                         d|d|	d|d j4                  d|dj                  d|d j
                  dj                  dj                  d|
d j6                  d|dj                  d j9                         d  j:                  d! j=                         d"j                  d# j?                  j                        d$|d%|d&t@        d' j                  d( jB                  d) j'                        d*jD                  S ),z
            List view
        Nr   r4   r8  c                 T    | dk(  rd } j                  j                  |             S )Nr   )r3   )r  rE   )pr;   r  s    r<   	pager_urlz+BaseModelView.index_view.<locals>.pager_url  s+    Av%%ioo1o&=>>r>   c                 l    |s|rj                   sd}j                  j                  | |            S )Nr+   )r5   r7   )r7   r  rE   )r   invertr  r;   r  s      r<   sort_urlz*BaseModelView.index_view.<locals>.sort_url  s3    F9+>+>%%ioo6To&RSSr>   c                 b    | sj                   } j                  j                  |             S )Nr  )r4   r  rE   )sr;   r  s    r<   page_size_urlz/BaseModelView.index_view.<locals>.page_size_url  s+    NN%%iooo&BCCr>   )r3   r5   r7   r8   r   r  
list_formsrB  rF  ra   rk   editable_columnslist_row_actionscountr  	num_pagescan_set_page_sizer  r3   r4   default_page_sizesort_columnr7   r  search_supportedclear_search_urlr8   r   r   filter_groupsactive_filtersfilter_argsr   actions_confirmationr   r   	get_value
return_urlr:   )FN)#r   rB  r  ru  r5   r4   r{  r3   r7   r8   r   r   rD  r   r  r   floatget_actions_listrF  r  rE   renderlist_templater   r   r   r  r   r   r   r  r  r   r  r:   )r;   rB  r  r4   r  r  r  rowr  r  r  r  r   r  rF  r  r  s   `               @r<   
index_viewzBaseModelView.index_view  s   
 ??**,KK --/	 --inn="%a.K ''94>>	 mmINNKATAT$-$4$4i6G6GS\ $ ^t 
$$ M59^^^5L
4,,S12M Dy)9!9:;III	?	T	D )-(=(=(?%%**,KK--ioo1CL>>HQH[H[EIFJ	 /> /L M t{{4
4
 "4
 $	4

 $4
 ++4
 "334
 "664
 "6684
 4
  4
   !4
" #44#4
$ (%4
& '4
(  )4
* #nn+4
0 "14
2  ))34
4 54
: "33;4
< .=4
> ##?4
@  $668A4
F MMG4
H 113I4
J %,,K4
L )))*;*;<M4
R S4
T "6U4
Z  [4
\ **]4
^ ))_4
` )))4a4
f !++g4
 4	
r>   z/new/)GETPOST)methodsc                    t               xs | j                  d      }| j                  st        |      S | j	                         }t        |d      r|j                  s| j                  | j                  |       | j                  |      r| j                  |      }|rt        t        d      d       dt        j                  v rt        t        j                        S dt        j                  v r?|dur.| j                  d	| j!                  |      |
      }t        |      S |}t        |      S t        | j#                  |d            S t%        | j&                  | j                        }| j(                  r,t        j*                  j-                  d      r| j.                  }n| j0                  }| j3                  ||||      S )z'
            Create model view
        rK  _validated_rulesetrd  z Record was successfully created.success_add_another_continue_editingT
.edit_view)r.  r   rM  widget_argsr   modal)r  	form_optsr  )r   rL  
can_creater   r;  hasattrr  rf  r   rI  r  r   r   r   r  r   r   rN  r   r   create_modalrA  r!  create_modal_templatecreate_templater  )r;   r  r  rz   r   r  r   s          r<   create_viewzBaseModelView.create_view#  s   
 )*Idll=.I
J''!t12$:Q:Q((1H1Ht(Td# %%d+Eg@A9M!W\\1#GKK00(GLL8D("ll<D<M<Me<TZdle $C=( )#C=( $D$<$<Ut$<$TUU)>)>(,(?(?A	 !1!1'!:11H++H{{8 $%.&0  2 	2r>   z/edit/c                    t               xs | j                  d      }| j                  st        |      S t	        t
        j                  d      }|t        |      S | j                  |      }| t        t        d      d       t        |      S | j                  |      }t        |d      r|j                  s| j                  | j                  |       | j                  |      r| j!                  ||      rt        t        d      d	       d
t
        j"                  v rt        | j                  d|            S dt
        j"                  v r+t        | j                  d| j%                  |                  S t        | j'                  |d            S t
        j(                  dk(  s|j*                  r| j-                  ||       t/        | j0                  | j                        }| j2                  r,t
        j                  j5                  d      r| j6                  }n| j8                  }| j;                  |||||      S )z%
            Edit model view
        rK  r.  Record does not exist.r  r8  r  rd  Record was successfully saved.r  r	  z.create_view)r   r
  r  )r.  Fr  r  r  r  )rz   r  r  r  )r   rL  r   r   r-   r   rA  r}  r   r   r>  r  r  rf  r   rI  r  r  r   rN  methoderrorsr  r   r   r   r!  edit_modal_templateedit_templater  )r;   r  r.  rz   r  r  r   s          r<   	edit_viewzBaseModelView.edit_viewQ  s   
 )*Idll=.I
}}J''#GLL$7:J''R ='23W=J''~~%~(t12$:Q:Q((1F1FT(Rd#  u-g>?K!W\\1#DLLZL$PQQ(GLL8#DLL$BSBSTYBZL$[\\ $D$<$<Uu$<$UVV>>U"dkk  r*)>)>(,(=(=?	 ??w||//8//H))H{{8!& $%.&0	  2 	2r>   z	/details/c                    t               xs | j                  d      }| j                  st        |      S t	        t
        j                  d      }|t        |      S | j                  |      }| t        t        d      d       t        |      S | j                  r,t
        j                  j                  d      r| j                  }n| j                  }| j                  ||| j                  | j                   |      S )z(
            Details model view
        rK  r.  r  r  r  )rz   details_columnsr  r  )r   rL  r   r   r-   r   rA  r}  r   r   r   r!  details_modal_templatedetails_templater  r   r  )r;   r  r.  rz   r   s        r<   details_viewzBaseModelView.details_view  s    
 )*Idll=.I
$$J''#GLL$7:J''R ='23W=J''',,"2"27";22H,,H{{8!&+/+@+@%)%:%:&0	  2 	2r>   z/delete/)r  c                    t               xs | j                  d      }| j                  st        |      S | j	                         }| j                  |      r|j                  j                  }| j                  |      }| t        t        d      d       t        |      S | j                  |      r3d}t        t        dd||      d       t        |      S t        |d	
       t        |      S )zE
            Delete model view. Only POST method is allowed.
        rK  r  r  r+   z Record was successfully deleted.z,%(count)s records were successfully deleted.)r  r  z"Failed to delete record. %(error)s)message)r   rL  r   r   rB  rI  r.  r  r}  r   r   r  r   r    )r;   r  r  r.  rz   r  s         r<   delete_viewzBaseModelView.delete_view  s    
 )*Idll=.I
J''!d#BLL$E}g67A
++   '?K"%12;=  
++'KL
##r>   z/action/c                 "    | j                         S )z-
            Mass-model action view.
        )handle_actionr\   s    r<   action_viewzBaseModelView.action_view  s    
 !!##r>   c                    t        | j                        D ]D  \  }}|| j                  D cg c]  \  }}|	 c}}vr(|j                  dk(  s8t	        d       | j                         }| j                  |j                        }||d   }| j                  d||j                  |j                  |j                  | j                        \  }}||fS c c}}w )NinnerzMacros are not implemented in export. Exclude column in column_formatters_export, column_export_list, or  column_export_exclude_list. Column: r   r  )r$   r   r   rF   r   r  ru  r5   r{  r7   r8   r   export_max_rows)r;   colfuncr
  r  r  r  r  s           r<   _export_datazBaseModelView._export_data  s     #4#@#@A 
	ICT-A-AB633BB}}') BEG 
	 --/	 --inn="%a.K mmA{I4G4G$-$4$4i6G6G.2.B.B $ Dt d{/ Cs   C
z/export/<export_type>/c                     t               xs | j                  d      }| j                  r|| j                  vr t	        t        d      d       t        |      S |dk(  r| j                  |      S | j                  ||      S )NrK  zPermission denied.r  rt   )	r   rL  
can_exportexport_typesr   r   r   _export_csv_export_tablib)r;   r  r  s      r<   exportzBaseModelView.export  ss    (*Idll=.I
;d6G6G#G'./9J''%##J//&&{J??r>   c                 
     j                         \  } G d dt              }t        j                   |              fd} j	                  d      }dt        |      }t        t         |             d|id	      S )
z:
            Export a CSV of records as a stream.
        c                       e Zd ZdZd Zy)'BaseModelView._export_csv.<locals>.Echozq
            An object that implements just the write method of the file-like
            interface.
            c                     |S )zr
                Write the value by returning it, instead of storing
                in a buffer.
                r@   )r;   r#  s     r<   writez-BaseModelView._export_csv.<locals>.Echo.write	  s	    
 r>   N)rF   rG   rH   rI   r:  r@   r>   r<   Echor8  	  s    r>   r;  c               3   0  K   j                   D  cg c]  } t        | d          }} j                  |       D ]J  }j                   D  cg c]   } t        j                  || d               " }} j                  |       L y c c} w c c} w w)Nr+   r   )r   r(   writerowr  )r   titlesr  valsr  r;   writers       r<   generatez+BaseModelView._export_csv.<locals>.generate	  s     040D0DE1j1&EFE//&)) ,!%!5!57 #4#8#8ad#CD 7 7ood++, F7s   BB(B%B4"Brt   )r  attachment;filename=Content-Dispositionztext/csvheadersmimetype)r/  objectrt   r@  r  r   r   r   )	r;   r  r  r;  rA  r  dispositionr  r@  s	   `      @@r<   r3  zBaseModelView._export_csv  s~     '')t
	6 
	 DF#	, ''E':2A(2KM
+*K8
 	
r>   c                    t          t        t        d      d       t        |      S | j	                  |      }dt        |      }t        j                  |      \  }}|sd}|r|d|}t        j                  | j                  D cg c]  }t        |d          c}      }| j                         \  }	}
|
D ]H  }| j                  D cg c]   }t        | j                  ||d               " }}|j                  |       J 	 	 |j                  |	      }t%        |d|i|      S c c}w c c}w # t        $ r t!        ||      }Y 1w xY w# t        t         j"                  f$ r% t        t        d
|      d       t        |      cY S w xY w)zL
            Exports a variety of formats using the tablib library.
        z Tablib dependency not installed.r  rB  zapplication/octet-streamz
; charset=r+   )rE  r   )formatz$Export type "%(type)s not supported.r  rC  rD  )tablibr   r   r   r  r   	mimetypes
guess_typeDatasetr   r(   r/  r  rO   r5  r  getattrUnsupportedFormatr   )r;   r  r  r  rH  rF  encodingr   dsr  r  r  r?  response_datas                 r<   r4  zBaseModelView._export_tablib#	  s    >'<=wGJ''''42A(2KM&11(;(1H+3X>H^^t?S?S$T!Z!%5$TU'')t 	CJNJ^J^_QJt44S!A$?@_D_IIdO		(9 "			 = *K8
 	
% %U
 ` " 9 'K 89 8 89 	('@*,-46J''	(s6   D)%D.D3 3EE 
EE ;FFz/ajax/lookup/c                    t         j                  j                  d      }t         j                  j                  d      }t         j                  j                  dt              }t         j                  j                  ddt              }| j                  j                  |      }|st        d       |j                  |||      D cg c]  }|j                  |       }}t        t        j                  |      d	      S c c}w )
Nr   queryoffsetr  limit
     zapplication/json)rF  )r   rA  r!  r  r   r	   r{  rJ  r   r
   dumps)r;   r   rU  rV  rW  loadermr  s           r<   ajax_lookupzBaseModelView.ajax_lookupM	  s    ||'  )!!(!5  "3 7%%))$/#J*0//%*OPQa PP

4(3EFF Qs   Dz/ajax/update/c                    | j                   st        d       | j                         }t        |      D ]I  }|j                  t
        j                  v s|j                  dk(  r/|j                  |j                         K | j                  |      r|j                  j                  }| j                  |      }|t        d      dfS | j                  ||      rt        d      S dj                  t               D cg c]  }| c}      }t        d|	      dfS |D ]W  }|j                   D ]F  }t#        |t              r"t        ddj                  |      	      dfc c S t        d|	      dfc c S  Y yc c}w )
zE
            Edits a single column of a record in list view.
        rY  
csrf_tokenNr  i  r  z, z"Failed to update record. %(error)s)r  )r   r	   rD  rA   r   r   r  rh  rI  list_form_pkr  r}  r   r  r]  r   r  r   )r;   r  r   pkrecordr  msgsr  s           r<   ajax_updatezBaseModelView.ajax_update\	  sw   
 ((#J~~ $Z 	-E

gll*

l0J  ,		- d#""''B\\"%F~78#==  v.?@@ yy1E1G!H##!HIC%)+,/0 0  9"\\ 9E!%.&'K-1YYu-= ?@C D D  ''K-2 458 9 999	 "Is   :	E6)NNNNNNNN)NNr2   )F)T)rt   )rF   rG   rH   rI   r  r   r   r   r1  r   r  r  r"  r  r  r!  r   r  r   r#   r`   rb   r   r   r   r   r9   rd   r   r   rf   r   r   rh   r   rj   rw  rl   r   r   r  r  rn   column_display_actionsr   simple_list_pagerr  r   r1  r&  form_columnsrp   form_overridesr   form_extra_fieldsr  r   r   r   rr   r,  r2  r4   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  r   r   r   r   r   r;  r>  rB  rD  rF  rI  rN  rS  rX  r   rf  re  r^  ro  rq  ru  rx  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   r  r   r  r  r  r#  r&  r)  r/  r5  r3  r4  r]  rd  __classcell__)r   s   @r<   r_   r_   d   s   $ J#H"J#
 J& ,M$+M/O!1' 9%<'>- JLLNMO }ndCK& ''<'>F 
 #' 
 "& %%8:KTVT>  $  $ **BDZ\`a)V %)!	 %)!	 !2BDIM 
 ((>(:(,.8 * **B*>*.0	   N N	  %%8%6%*, "  $" 
 D O  I L& ))@)@)-/ N @ , N: J6 O 
 **B*>*,. O 7L I 
 SWLP+\++$%03(>TB$
S
.?0D"


"
 W*
6.8 KP$!>F
A?-"?A-D(	L$I),
	KC'   F2	E$ $	.$$$	#;G: &507(-^ 
 
& 
 
&
$$$ C[z
 z
x G_-+2 .+2Z Ho.12 /12f K2 2< J	* $ + $D J	*$ +$> $%
@ &
@'
R(
T OG G OY/)9 0)9r>   r_   )JrU  r  rt   rL  r  mathr   r  werkzeug.utilsr   flaskr   r   r   r   r	   r
   r   r   r   rK  ImportErrorwtforms.fieldsr   wtforms.fields.corer   wtforms.validatorsr   r   flask_admin.babelr   r   flask_admin.baser   r   flask_admin.formr   r   r   flask_admin.modelr   r   r   flask_admin.actionsr   flask_admin.helpersr   r   r   r    flask_admin.toolsr"   flask_admin._backwardsr#   flask_admin._compatr$   r%   r&   r'   r(   r)   r*   helpersr,   r-   ajaxr.   compiler  r  rG  r0   rK   r_   r@   r>   r<   <module>r~     s     	 
     *H H H ' , = / - 6 6 8 8 ,D D ) /R R R : ! L)BJJt$  "v  "F"& "0b$9Hl b$9k  Fs   C= =DD