Django рд░рд┐рдкреЛрд░реНрдЯ рд╕рд░реНрд╡рд░

рд╢реБрдн рджрд┐рдиред

рдРрд╕рд╛ рд╣реБрдЖ рдХрд┐ рдореЗрд░рд╛ рдХрд╛рдо рд░рд┐рдкреЛрд░реНрдЯ рд▓рд┐рдЦрдиреЗ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИред
рдореИрдВрдиреЗ рдЗрд╕реЗ рд▓рдЧрднрдЧ 8 рд╕рд╛рд▓ рд╕рдорд░реНрдкрд┐рдд рдХрд┐рдпрд╛ред рд░рд┐рдкреЛрд░реНрдЯ рд╡реНрдпрд╛рдкрд╛рд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдФрд░ рд╕реВрдЪрдирд╛ рдХреА рдЖрдВрдЦреЗрдВ рд╣реИрдВ
рдкрд░рд┐рдЪрд╛рд▓рди рдирд┐рд░реНрдгрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХред

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдорд╛рд░реЗ рд╡рд┐рднрд╛рдЧ рдиреЗ рд░рд┐рдкреЛрд░реНрдЯ рдмрдирд╛рдИ,
- рдЖрдЙрдЯрд▓реБрдХ рдкрд░ рдХрд╛рд░реНрдп рдХрд░рдирд╛
- рдПрдХ sql рдХреНрд╡реЗрд░реА рдХреА рд░рдЪрдирд╛
- рдЧреНрд░рд╛рд╣рдХ рдХреЛ xls рдореЗрдВ рдкрд░рд┐рдгрд╛рдо рднреЗрдЬрдирд╛
- рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рдорд╛рдорд▓реЗ рдореЗрдВ, рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рдХрд╣реАрдВ рдФрд░ sql рдХреЛрдб рдХреА рдмрдЪрдд (рдФрд░ рдХрднреА-рдХрднреА рдмрдЪрдд рдирд╣реАрдВ)

рд▓реЗрдХрд┐рди рдпрд╣ рдЙрдмрд╛рдК рдФрд░ рдирд┐рд░реНрдмрд╛рдз рдерд╛ред рдпрд╣ рдХреИрд╕реЗ рд╕рд░рд▓ PHP рдЖрд╡реЗрджрди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЖрдпрд╛ рдерд╛,
рдЬрд┐рд╕рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рд░рд┐рдкреЛрд░реНрдЯ рдХреЛ рдПрдХ рд╡рд░реНрдЧ рдХреЗ рд╕рд╛рде рдПрдХ php рдлрд╝рд╛рдЗрд▓ рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдЬрд┐рд╕рдореЗрдВ рдПрдХрд▓ (рдирд┐рд░реНрдорд╛рдгрдХрд░реНрддрд╛ рдХреЗ рдЕрд▓рд╛рд╡рд╛) рд╢реЛ () рд╡рд┐рдзрд┐ рдереА

рдЗрд╕ рд░реВрдк рдореЗрдВ, рдкреНрд░рдгрд╛рд▓реА 5.5 рд╕рд╛рд▓ рддрдХ рдЬреАрд╡рд┐рдд рд░рд╣реА, рдЬрд┐рд╕рдХреЗ рджреМрд░рд╛рди рдореЗрд░реЗ рдФрд░ рдПрдХ рдЕрдиреНрдп рд╡реНрдпрдХреНрддрд┐ рджреНрд╡рд╛рд░рд╛ 500 рд╕реЗ рдЕрдзрд┐рдХ рд╡рд┐рднрд┐рдиреНрди рд░рд┐рдкреЛрд░реНрдЯреЗрдВ рд▓рд┐рдЦреА рдЧрдИрдВред
рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ, рдЕрдиреБрднрд╡ рдкреНрд░рдХрдЯ рд╣реБрдЖ рдФрд░ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реЛ рдЧрдпрд╛ рдХрд┐ рдмрд╣реБрдд рдХреБрдЫ (рдпрджрд┐ рд╕рднреА рдирд╣реАрдВ) рдЧрд▓рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдФрд░ PHP рдЕрдм рдЦреБрд╢ рдирд╣реАрдВ рдерд╛ред

рд░рд┐рдкреЛрд░реНрдЯ рд╕рд░реНрд╡рд░ рдХреЛ django рдореЗрдВ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рдерд╛, рдЬрд╣рд╛рдВ "рд╡реНрдпрд╡рд╕реНрдерд╛рдкрдХ рдкреИрдирд▓" рдерд╛ рдФрд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛрдб рдХреЛ рдЕрдм рдареАрдХ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ, рдХрдИ рд╡рд┐рдЪрд╛рд░ рдлрд┐рд░ рд╕реЗ рдЬрдорд╛ рд╣реБрдП,
рдирддреАрдЬрддрди, рд╕рд░реНрд╡рд░ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рдерд╛ред

рдореИрдВрдиреЗ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рд╡рд░реНрддрдорд╛рди рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рд╕рдореБрджрд╛рдп рдореЗрдВ рдкреЗрд╢ рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛, рд╢рд╛рдпрдж рдпрд╣ рдХрд┐рд╕реА рдХреЗ рд▓рд┐рдП рдЬреАрд╡рди рдЖрд╕рд╛рди рдмрдирд╛ рджреЗрдЧрд╛,
рд░рд┐рдкреЛрд░реНрдЯрд┐рдВрдЧ рд░реВрдЯреАрди рдХреЛ рд╣рдЯрд╛ рджрд┐рдпрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рдПрдХ рдорд╢реАрди рдкрд░ рд░рдЦ рджрд┐рдпрд╛ рд╣реИ рдЬреЛ рд╕реИрдХрдбрд╝реЛрдВ рдмрд╛рд░ рд░рд┐рдкреЛрд░реНрдЯ рддреИрдпрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИ
рд╡рд┐рднрд┐рдиреНрди рдЗрдирдкреБрдЯ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕реИрдХрдбрд╝реЛрдВ рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рд╣рдЬрд╛рд░реЛрдВред

рдпрд╣ рдПрдХ рдХрд╛рдо рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдЙрдкрдХрд░рдг рд╣реИ рдЬрд┐рд╕реЗ рдЖрдк (рдпрджрд┐ рдЖрдк рдЪрд╛рд╣реЗрдВ) рдЕрдкрдиреЗ рдХрд╛рдо рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ,
рдЬрд┐рд╕реЗ рд╣рдо рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдкрд╕рдВрдж рдХрд░рддреЗ рд╣реИрдВред



рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреА рд╕рдВрд░рдЪрдирд╛


рдХреЛрдИ рднреА рдЗрдЪреНрдЫреБрдХ рд╡реНрдпрдХреНрддрд┐ рддреБрд░рдВрдд https://bitbucket.org рдкрд░ рд╕реНрд░реЛрдд рдХреЛрдб рджреЗрдЦ рд╕рдХрддрд╛ рд╣реИ

рдЕрд╡рдзрд╛рд░рдгрд╛ рдФрд░ рдмреБрдирд┐рдпрд╛рджреА рддрддреНрд╡



рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рд░рд┐рдкреЛрд░реНрдЯ рдХрд╛ рдПрдХ рд╕реЗрдЯ рд╣реЛрддрд╛ рд╣реИред
- рд░рд┐рдкреЛрд░реНрдЯ рдХрдордЬреЛрд░ рд░реВрдк рд╕реЗ (рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд░реВрдк рд╕реЗ рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ) рдПрдХ рджреВрд╕рд░реЗ рдХреЗ рд╕рд╛рде рдЬреБрдбрд╝реА рд╣реБрдИ рд╣реИрдВ, рддрд╛рдХрд┐ рдбреЗрд╡рд▓рдкрд░ рдХреЛ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рд╣реЛ рд╕рдХреЗ рдХрд┐ рд╡рд╣ рдХрд┐рд╕реА рдПрдХ рдХреЛ рд╕рдВрдкрд╛рджрд┐рдд рдХрд░рдХреЗ рдЕрдиреНрдп рд░рд┐рдкреЛрд░реНрдЯреЛрдВ рдореЗрдВ рдХреБрдЫ рднреА рдмрд░реНрдмрд╛рдж рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред
- рд░рд┐рдкреЛрд░реНрдЯ рддрддреНрд╡ рд░рд┐рдкреЛрд░реНрдЯ рдХреЗ рднреАрддрд░ рдХрд╕рдХрд░ рдЬреБрдбрд╝реЗ рд╣реБрдП рд╣реИрдВ рдФрд░ рдПрдХ рджреВрд╕рд░реЗ рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░рддреЗ рд╣реИрдВред

рд░рд┐рдкреЛрд░реНрдЯ рдПрдХ рдкрджрд╛рдиреБрдХреНрд░рдо рдореЗрдВ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдирд╣реАрдВ рд╣реЛрддреА рд╣реИрдВ (рдЙрдиреНрд╣реЛрдВрдиреЗ рдЗрд╕реЗ рдЫреЛрдбрд╝ рджрд┐рдпрд╛), рд▓реЗрдХрд┐рди рдЯреИрдЧ рдХреЗ рдПрдХ рд╕реЗрдЯ рдХреЗ рд╕рд╛рде рдЪрд┐рд╣реНрдирд┐рдд рд╣реИрдВред
рдореБрдЦреНрдп рд░рд┐рдкреЛрд░реНрдЯрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рдкрд░, рдЖрдк рдЙрди рдЯреИрдЧреЛрдВ рдХреЗ рд╡рд╛рдВрдЫрд┐рдд рд╕рдВрдпреЛрдЬрди рдХреЛ рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреНрд▓рд┐рдХ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдлрд╝рд┐рд▓реНрдЯрд░ рдХреА рддрд░рд╣ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ
рдФрд░ рд░рд┐рдкреЛрд░реНрдЯ рдХреА рдЦреЛрдЬ рдХрд░реЗрдВред

рд░рд┐рдкреЛрд░реНрдЯ рддрддреНрд╡ "рдЖрд▓рд╕реА" рд╣реИрдВ рдФрд░ рд╡рд┐рдЬреЗрдЯ рд▓реЗрдЖрдЙрдЯ рд╕реНрддрд░ рдкрд░ рдЕрд╕реЗрдВрдмрд▓реА рдХреЗ рд╕рдордп рдирд┐рд╖реНрдкрд╛рджрд┐рдд рд╣реЛрдиреЗ рд▓рдЧрддреЗ рд╣реИрдВ,
рдЬреЛ рдХреЗрд╡рд▓ рдЙрди рдбреЗрдЯрд╛рдмреЗрд╕ рдкреНрд░рд╢реНрдиреЛрдВ рдХреЛ рдкреВрд░рд╛ рдХрд░рдирд╛ рд╕рдВрднрд╡ рдмрдирд╛рддрд╛ рд╣реИ рдЬреЛ рдЖрд╡рд╢реНрдпрдХ рд╣реИрдВ,
рд░рд┐рдкреЛрд░реНрдЯ рдореЗрдВ рд╕рдореВрд╣реАрдХреГрдд рдбреЗрдЯрд╛ рдФрд░ рдбреНрд░рд┐рд▓рдбрд╛рдЙрди рд░рдЦрдирд╛ред
рд╕реНрд░реЛрдд рд╕реНрддрд░ рдкрд░ рдбреЗрдЯрд╛ рдХреЛ рдХреИрд╢рд┐рдВрдЧ рдХрд░рдХреЗ, рдХрдИ рд╡рд┐рдЬреЗрдЯ рдЬреЛ рдПрдХ рд╕реНрд░реЛрдд рд╕реЗ рдбреЗрдЯрд╛ рдХрд╛ рдЙрддреНрдкрд╛рджрди рдХрд░рддреЗ рд╣реИрдВ, рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рдХреЗрд╡рд▓ рдПрдХ рдХреНрд╡реЗрд░реА рджреЗрддреЗ рд╣реИрдВред
<!--     ,    ,     --> {% if get.detail == 'table' %} {{table.some_table_detail}} {% elif get.detail == 'chart' %} {{charts.some_chart}} {% else %} {{tables.grouped_table}} {% endif %} 


рдЙрдкрд▓рдмреНрдзрддрд╛ рдХреЗ рддрдереНрдп рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд░рд┐рдкреЛрд░реНрдЯ рддрдХ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреА рдкрд╣реБрдВрдЪ рдХреЗ рд▓рд┐рдП рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИрдВред
рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд░рд┐рдкреЛрд░реНрдЯ рдХреЗ рднрд╛рдЧ рдпрд╛ рдбреЗрдЯрд╛ рдХреЗ рднрд╛рдЧ рддрдХ рдкрд╣реБрдБрдЪ рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
 select * from some_table t where 1 = 1 --   {% if user_params.only_filials %}and filial_id in ({{user_params.only_filials|join:","}}){% endif %} --   ,    %s {% if user_params.only_sectors %}and sector_id = [[user_params.only_sectors.0]]{% endif %} 


рдпрджрд┐ рдЖрдкрдХреЛ рдЯреЗрдореНрдкрд▓реЗрдЯ рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рдкреНрд░рдмрдВрдзрдХ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рдХрд▓реНрдк рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ __call__
рдпрджрд┐ рдХрдИ рд╡рд┐рдХрд▓реНрдк рд╕рдВрднрд╡ рд╣реИрдВ, рддреЛ рд╢рдмреНрджрдХреЛрд╢ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд▓рд┐рдП __getitem__ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред

рдкреНрд░рддреНрдпреЗрдХ рд░рд┐рдкреЛрд░реНрдЯ рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╢рд╛рдорд┐рд▓ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ:

рдкрд░реНрдпрд╛рд╡рд░рдг рдкреНрд░рдмрдВрдзрдХ
 class EnvirementManager(object): u'''    , render    ,    .. ''' def __init__(self, **kwargs): self._env = kwargs def render(self, text, **dict): u'''     ''' return render_string(text, self._dict_mix(dict)) def render_template_compiled(self, template, **dict): u'''     ''' return template.render(Context(self._dict_mix(dict))) def render_template(self, path, **dict): u'''  ''' return render_to_string(path, self._dict_mix(dict), context_instance=RequestContext(self._env['request'])) def render_sql(self, sql, **dict): u'''             ''' sql_rendered = self.render(sql, **dict) binds = [] for bind_token in re.findall(r'\[{2}.+\]{2}', sql_rendered): env_path = bind_token[2:-2] binds.append(attribute_by_name(self._env, env_path)) sql_rendered = sql_rendered.replace(bind_token, u'%s') return (sql_rendered, binds) def _dict_mix(self, dict): if dict: e = self._env.copy() e.update(dict) else: e = self._env return e def get(self, name, value=None): return self._env.get(name, value) def __getitem__(self, name): return self._env[name] def __setitem__(self, name, value): self._env[name] = value 


рдирд╛рдорд╛рдВрдХрд┐рдд рддрд░реНрдХреЛрдВ рджреНрд╡рд╛рд░рд╛ рдЖрд░рдВрдн рдХрд┐рдпрд╛ рдЧрдпрд╛ рдФрд░ рд╕рдм рдХреБрдЫ рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдпрд╛ рдЧрдпрд╛
рд╡реИрд░рд┐рдПрдмрд▓ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдП рдЬреЛ рдЖрд░рдВрднрд┐рдХ рд╣реИрдВред

рдЗрд╕рдХреЗ рдХрд╛рд░рдг, рд╣рдо рдХрд╣реАрдВ рд╕реЗ рднреА рдЪрд░ рдХреЗ рдЬреНрдЮрд╛рдд рд╕реЗрдЯ рдХреА рдЙрдкрд▓рдмреНрдзрддрд╛ рдХреА рдЧрд╛рд░рдВрдЯреА рджреЗ рд╕рдХрддреЗ рд╣реИрдВред
рдпрд╣ рдПрд╕рдХреНрдпреВрдПрд▓ рдкреНрд░рд╢реНрдиреЛрдВ рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рдбреЗрдЯрд╛ рд╕реНрд░реЛрдд рд╣реИрдВ (рд▓реЗрдХрд┐рди рдЙрд╕ рдкрд░ рдФрд░ рдЕрдзрд┐рдХ)

рдбреЗрдЯрд╛ рд╕реНрд░реЛрдд рдкреНрд░рдмрдВрдзрдХ
 class DatasetManager(object): u'''    ''' def __init__(self, request, dataset, env): u'''  ''' self._request = request self._dataset = dataset self._env = env self._cache = [] self._xml = None if self._dataset.xml_settings: self._xml = etree.fromstring(self._env.render(self._dataset.xml_settings)) def get_data(self): u'''        ''' if not self._cache: self._cache = [[], []] (sql, binds) = self._env.render_sql(self._dataset.sql) cursor = self._modify_cursor(connections['reports'].cursor()) cursor.execute(sql, binds) #    xml_columns = {} if self._xml not in (None, ''): for xml_column in self._xml.xpath('/xml/columns/column'): attrs = xml_column.attrib xml_columns[force_unicode(attrs['name'])] = force_unicode(attrs['alias']) #   (  ,  ) #      ,     for field in cursor.description: name_unicode = force_unicode(field.name) self._cache[0].append(xml_columns[name_unicode] if name_unicode in xml_columns else name_unicode) self._cache[1] = cursor.fetchall() return self._cache def __getitem__(self, name): u'''         ''' if name == 'sql': return self._env.render(self._dataset.sql) elif name == 'render': (sql, binds) = self._env.render_sql(self._dataset.sql) return {'sql': sql, 'binds': binds} elif name == 'data': (fields, data) = self.get_data() return [dict(zip(fields, row)) for row in data] def _modify_cursor(self, cursor): u'''    (      ), ,  Oracle    ,  number_as_string = True (    backends django) ''' return cursor 


рдЖрдкреВрд░реНрддрд┐:
- рдЯрдкрд▓ рдХреЗ рд░реВрдк рдореЗрдВ рдбреЗрдЯрд╛ (рдлрд╝реАрд▓реНрдб_рдирд╛рдо, рдкрдВрдХреНрддрд┐рдпрд╛рдБ,)
рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рд╡рд┐рдЧреЗрдЯреНрд╕ рдХреЗ рджреГрд╢реНрдп рдХреЗ рд▓рд┐рдП, рдПрдХреНрд╕реЗрд▓ рдореЗрдВ рдЙрддрд╛рд░рдирд╛
- рд╢рдмреНрджрдХреЛрд╢реЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рдХреЗ рд░реВрдк рдореЗрдВ рдбреЗрдЯрд╛ (рдкреНрд░рддреНрдпреЗрдХ рдкрдВрдХреНрддрд┐ рдПрдХ рд╢рдмреНрджрдХреЛрд╢ рд╣реИ)
HTML рдХреЗ рд╕реНрд░реЛрдд рдФрд░ рдкреАрдврд╝реА рддрдХ рд╕реАрдзреА рдкрд╣реБрдВрдЪ рдХреЗ рд▓рд┐рдП, рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореИрдиреЗрдЬрд░, рд▓реЗрдЖрдЙрдЯ рдореИрдиреЗрдЬрд░ рдореЗрдВ рд╕реАрдПрд╕рдПрд╕ рдХреЛрдб (рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдереЛрдбрд╝реА рджреЗрд░ рдмрд╛рдж)
- рдмрд╛рдЗрдВрдбрд┐рдВрдЧ рд╡реЗрд░рд┐рдПрдмрд▓ рдХреЛ рдкреНрд░реЛрд╕реЗрд╕ рдХрд┐рдП рдмрд┐рдирд╛ sql рдХреЛрдб
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдиреЗрд╕реНрдЯреЗрдб рдбреЗрдЯрд╛ рд╕реНрд░реЛрддреЛрдВ рдХреЛ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:
  select key, count(1) from ({{datasets.base_dataset.sql}}) group by key 

- рдПрд╕рдХреНрдпреВрдПрд▓ рдХреЛрдб рдФрд░ рдмрд╛рдзреНрдпрдХрд╛рд░реА рдЪрд░
рд╕рд┐рд░реНрдл рдбрд┐рдмрдЧрд┐рдВрдЧ рдФрд░ рд░рд┐рдкреЛрд░реНрдЯрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП

рдЗрд╕рдХреЗ рдХрд╛рд░рдг, рдЖрдк рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
- рдкрд░реНрдпрд╛рд╡рд░рдг рдкреНрд░рдмрдВрдзрдХ рдХреЗ рдЪрд░ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдордХреНрдЦреА рдкрд░ sql рдХреНрд╡реЗрд░реА рдмрджрд▓реЗрдВ
- рдПрдХ рдЕрдиреБрд░реЛрдз рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдЖрдк рджреВрд╕рд░реЛрдВ рдХреЛ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рдЖрдкрдХрд╛ рд╕рдореВрд╣реАрдХрд░рдг рдФрд░ рд╡рд┐рд╕реНрддрд╛рд░ рдХрднреА рдЕрд▓рдЧ рди рд╣реЛ,
рдЪреВрдБрдХрд┐ рд╡реЗ рдПрдХ рд╕реНрд░реЛрдд рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИрдВ, рдФрд░ рдЖрдк рд╕рдореВрд╣рди рдХреЛ рдирд┐рдЦрд╛рд░рдирд╛ рдХрднреА рдирд╣реАрдВ рднреВрд▓реЗрдВрдЧреЗ рдФрд░ рдЗрд╕реЗ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдХрд░рдирд╛ рднреВрд▓ рдЬрд╛рдПрдВрдЧреЗ
- рджреВрд╕рд░реЗ рдХреЗ рдЧрддрд┐рд╢реАрд▓ рд╡рд┐рдзрд╛рдирд╕рднрд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдбреЗрдЯрд╛ рд╕реНрд░реЛрдд рд╕реЗ рдЪрдпрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд░рд┐рдкреЛрд░реНрдЯрд┐рдВрдЧ рдЕрд╡рдзрд┐ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдорд╛рд╕рд┐рдХ, рдорд╛рд╕рд┐рдХ (рдпрд╛ рд╕рд╛рдкреНрддрд╛рд╣рд┐рдХ) рдЖрдзрд╛рд░ рдкрд░ рдХреНрд╡реЗрд░реА рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рдЕрдЬреНрдЮрд╛рдд рд╕рдВрдЦреНрдпрд╛ рдХреЗ рдХреЙрд▓рдо рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП (рдкреНрд░рдкрддреНрд░ рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдиреАрдЪреЗ рдЙрдирдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ)
рдФрд░ рдпрд╣ рд╕рдм рдбреЗрдЯрд╛рдмреЗрд╕ рдХреА рдХреНрд╖рдорддрд╛рдУрдВ рдХреА рдкрд░рд╡рд╛рд╣ рдХрд┐рдП рдмрд┐рдирд╛ (рдкрд┐рд╡рдЯ рдХреЗ рдмрд┐рдирд╛ | рдмрд┐рдирд╛ рдзреБрд░реА рдХреЗ oracle рдФрд░ xml_query oracle)

рдлрд╝рд┐рд▓реНрдЯрд░ рдкреНрд░рдмрдВрдзрдХ
 class FilterManager(object): u'''     ''' def __init__(self, request, filter_obj, env): u'''  ''' self._request = request self._filter_obj = filter_obj self._env = env self._form_instance = None self._changed_data = {} #    ,   POST- #    ,     ,    self._changed_data if self._request.method == 'POST' and int(self._request.POST['filter_id']) == self._filter_obj.id: self._form_instance = self._get_form_class()(self._request.POST) if self._form_instance.is_valid(): data = self._form_instance.cleaned_data for key, value in data.items(): if self._env['f'].get(key) != value: self._changed_data[key] = value def get_changed_data(self): return self._changed_data def get_form(self): u'''     ''' try: #       , ( ) #       if self._form_instance is None: self._form_instance = self._get_form_class()(initial=self._env['f']) html = self._env.render('{% load custom_filters %}' + self._filter_obj.html_layout, form=self._form_instance) return self._env.render_template('reports_filter.html', form_html=html, filter=self._filter_obj) except Exception as e: return e def __call__(self): u'''     ''' try: return self.get_form() except Exception as e: return e def _get_form_class(self): u'''       ''' form_attrs = {} filter_widgets = (DateField, ChoiceField, MultipleChoiceField, BooleanField, CharField, CharField, DateRangeField) for item in self._filter_obj.form_items.all(): kwargs = {'label': item.title, 'required': False} if item.xml_settings: xml = xml = etree.fromstring(self._env.render(item.xml_settings)) else: xml = None if item.widget_type == 0: kwargs['widget'] = forms.DateInput(attrs={'class': 'date'}) elif item.widget_type in (1, 2): choices = [] for option in xml.xpath('/xml/options/option'): choices.append((option.attrib['id'], option.attrib['value'])) sql = xml.xpath('/xml/sql') if sql: curs = connections['reports'].cursor().execute(sql[0].text) for row in curs.fetchall(): choices.append((row[0], row[1])) kwargs['choices'] = choices elif item.widget_type == 4: kwargs['max_length'] = 50 elif item.widget_type == 5: default = xml.xpath('/xml/value') kwargs['widget'] = forms.HiddenInput(attrs={'value': default[0].text}) form_attrs[item.key] = filter_widgets[item.widget_type](**kwargs) filter_form = type(str(self._filter_obj.title), (forms.Form,), form_attrs) return filter_form 



рдпрд╣рд╛рдВ рд╕рдм рдХреБрдЫ рдХрд╛рдлреА рддреБрдЪреНрдЫ рд╣реИред рд╣рдо рдлреЙрд░реНрдо рдЗрдХрдЯреНрдард╛ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдлреЙрд░реНрдо рдФрд░ рдмрджрд▓реЗ рд╣реБрдП рдбреЗрдЯрд╛ рджреЗрддреЗ рд╣реИрдВ

рдЯреЗрдмрд▓ рд╡рд┐рдЬреЗрдЯ
 class WidgetTableManager(object): u'''      ''' def __init__(self, request, widget_obj, dataset, env): u'''  ''' self._request = request self._widget_obj = widget_obj self._dataset = dataset self._env = env self._xml = None if widget_obj.xml_settings: self._xml = etree.fromstring(self._env.render(widget_obj.xml_settings).replace('[[', '{{').replace(']]', '}}')) def get_html(self): u'''  html-  ''' (fields, data) = self._dataset.get_data() field_settings = {} table_settings = {} if self._xml is not None: table_settings_node = xml_node(self._xml, '/xml/table') if table_settings_node is not None: table_settings = table_settings_node.attrib for xml in self._xml.xpath('/xml/fields/field'): xml_attributes = dict(xml.attrib) field_name = xml_attributes['name'] if 'lnk' in xml_attributes: xml_attributes['tpl_lnk'] = Template(force_unicode(xml_attributes['lnk'])) if 'cell_attributes' in xml_attributes: xml_attributes['tpl_cell_attributes'] = Template(force_unicode(xml_attributes['cell_attributes'])) field_settings[field_name] = xml_attributes #     fields_visible = [] for index, field_name in enumerate(fields): settings = field_settings.get(field_name, {}) if 'display' in settings and settings['display'] == '0': continue fields_visible.append((index, field_name, settings)) #       rows = [] for row in data: row_dict = dict(zip(fields, row)) row_settings = {} #    if 'field_row_style' in table_settings: row_settings['row_style'] = row_dict[table_settings['field_row_style']] if 'field_row_attributes' in table_settings: row_settings['row_attributes'] = row_dict[table_settings['field_row_attributes']] #        fields_set = [] for index, field_name, settings in fields_visible: field = {'name': field_name, 'value': row[index]} #         if 'tpl_lnk' in settings and ('lnk_enable_field' not in settings or row_dict[settings['lnk_enable_field']] not in (0, '0', '', None)): field['lnk'] = self._env.render_template_compiled(settings['tpl_lnk'], row=row_dict) #   if 'tpl_cell_attributes' in settings: field['cell_attributes'] = settings['tpl_cell_attributes'].render(Context(row_dict)) field['settings'] = settings fields_set.append(field) rows.append({'settings': row_settings, 'fields': fields_set}) return render_to_string('reports_widget_table.html', {'fields': fields_visible, 'rows': rows, 'widget_obj': self._widget_obj}) def __call__(self): u'''  ,   ''' try: return self.get_html() except Exception as e: return u'   %s: "%s"' % (self._widget_obj.title, e) 



рдпрд╣ рдбреЗрдЯрд╛ рд╕реНрд░реЛрдд рд╕реЗ рдбреЗрдЯрд╛ рд▓реЗрддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рддрд╛рд▓рд┐рдХрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИред рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ
- рд╕реНрд╡рд░реВрдкрдг
- рд▓рд┐рдВрдХ рдХреА рдкреАрдврд╝реА (рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рд╕реА рдЕрдиреНрдп рддрд╛рд▓рд┐рдХрд╛, рдЧреНрд░рд╛рдлрд╝ рдпрд╛ рдПрдХреНрд╕реЗрд▓ рдореЗрдВ рдХреЛрд╢рд┐рдХрд╛рдУрдВ рдХреЛ рдбреНрд░рд┐рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ)
- рдордирдорд╛рдиреЗ рдврдВрдЧ рд╕реЗ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреА рдЙрддреНрдкрддреНрддрд┐ (рдХрд╛рд░реНрдпрд╢реАрд▓ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд▓рд┐рдП, рдкрд░рд┐рдгрд╛рдореА рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреЛ рдЫрд┐рдкрд╛рдирд╛ рдпрд╛ рджрд┐рдЦрд╛рдирд╛ рдЖрджрд┐ред

рд╡рд┐рдЬреЗрдЯ - рдЪрд╛рд░реНрдЯ
 class WidgetChartManager(object): u'''   ''' def __init__(self, request, chart_obj, dataset, env): u'''  ''' self._request = request self._chart_obj = chart_obj self._dataset = dataset self._env = env self._xml = etree.fromstring(self._env.render(self._chart_obj.xml_settings)) print 1 def __call__(self): u'''     ''' print 2 try: return self.get_chart() except Exception as e: print unicode(e) return unicode(e) def get_chart(self): u''' html     ''' (fields, data) = self._dataset.get_data() return self._env.render_template('reports_widget_chart.html', settings=xml_to_dict(xml_node(self._xml, '/xml')), data=json.dumps([dict(zip(fields, row)) for row in data], cls=JSONEncoder), chart_obj=self._chart_obj, ) 



рдпрд╣рд╛рдБ рднреА рд╕рд░рд▓ рд╣реИред рдпрд╣ рд╕реНрд░реЛрдд рд╕реЗ рдбреЗрдЯрд╛ рд▓реЗрддрд╛ рд╣реИ, XML рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХреЛ рдПрдХ рдбрд┐рдХреНрдЯреЗрдЯ рдореЗрдВ рддрдмреНрджреАрд▓ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░рддрд╛ рд╣реИ,
рдЧреНрд░рд╛рдлрд╝ рдХреЗ рд▓рд┐рдП рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛрдб рдПрдХрддреНрд░рд┐рдд рдХрд░рдирд╛ (amcharts рджреНрд╡рд╛рд░рд╛ рдкреНрд░рдпреБрдХреНрдд)
XML рдиреЛрдбреНрд╕ рдХреЗ рдЯреИрдЧ рдХреЛ рдкреИрд░рд╛рдореАрдЯрд░ рдирд╛рдо, рдЯреЗрдХреНрд╕реНрдЯ рдХреЛ рдкреИрд░рд╛рдореАрдЯрд░ рдорд╛рди рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ,
рд╡рд╣ рдпрд╣ рд╣реИ рдХрд┐, рдЖрдк рдЖрдордЪрд░реНрд╕ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рд▓рдЧрднрдЧ рд╕рднреА рдорд╛рдкрджрдВрдбреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ,
рдмрд╕ рд╡рд╛рдВрдЫрд┐рдд рдЕрдиреБрднрд╛рдЧ рдореЗрдВ рд╡рд╛рдВрдЫрд┐рдд рдЯреИрдЧ рд░рдЦрдирд╛

рдФрд░, рд╕реИрджреНрдзрд╛рдВрддрд┐рдХ рднрд╛рдЧ рдХреЗ рдкреВрд░рд╛ рд╣реЛрдиреЗ рдХреЗ рд░реВрдк рдореЗрдВ, рдореИрдВ рдЙрд╕ рд╡рд░реНрдЧ рдХрд╛ рдХреЛрдб рд▓рд╛рддрд╛ рд╣реВрдВ рдЬреЛ рдпрд╣ рд╕рдм рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рддрд╛ рд╣реИ,
рд╡рд┐рдЧреЗрдЯреНрд╕ рд░рдЦрдХрд░, рдпрд╛ xls рдпрд╛ рдПрдХ рдордирдорд╛рдирд╛ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ (рдПрдХреНрд╕рдЯреЗрдВрд╢рди .doc рдпрд╛ .xls рдХреЗ рд╕рд╛рде html) рд▓реМрдЯрд╛рдХрд░ред

рдЯреЗрдмрд▓ рд╡рд┐рдЬреЗрдЯ
 class WidgetTableManager(object): u'''      ''' def __init__(self, request, widget_obj, dataset, env): u'''  ''' self._request = request self._widget_obj = widget_obj self._dataset = dataset self._env = env self._xml = None if widget_obj.xml_settings: self._xml = etree.fromstring(self._env.render(widget_obj.xml_settings).replace('[[', '{{').replace(']]', '}}')) def get_html(self): u'''  html-  ''' (fields, data) = self._dataset.get_data() field_settings = {} table_settings = {} if self._xml is not None: table_settings_node = xml_node(self._xml, '/xml/table') if table_settings_node is not None: table_settings = table_settings_node.attrib for xml in self._xml.xpath('/xml/fields/field'): xml_attributes = dict(xml.attrib) field_name = xml_attributes['name'] if 'lnk' in xml_attributes: xml_attributes['tpl_lnk'] = Template(force_unicode(xml_attributes['lnk'])) if 'cell_attributes' in xml_attributes: xml_attributes['tpl_cell_attributes'] = Template(force_unicode(xml_attributes['cell_attributes'])) field_settings[field_name] = xml_attributes #     fields_visible = [] for index, field_name in enumerate(fields): settings = field_settings.get(field_name, {}) if 'display' in settings and settings['display'] == '0': continue fields_visible.append((index, field_name, settings)) #       rows = [] for row in data: row_dict = dict(zip(fields, row)) row_settings = {} #    if 'field_row_style' in table_settings: row_settings['row_style'] = row_dict[table_settings['field_row_style']] if 'field_row_attributes' in table_settings: row_settings['row_attributes'] = row_dict[table_settings['field_row_attributes']] #        fields_set = [] for index, field_name, settings in fields_visible: field = {'name': field_name, 'value': row[index]} #         if 'tpl_lnk' in settings and ('lnk_enable_field' not in settings or row_dict[settings['lnk_enable_field']] not in (0, '0', '', None)): field['lnk'] = self._env.render_template_compiled(settings['tpl_lnk'], row=row_dict) #   if 'tpl_cell_attributes' in settings: field['cell_attributes'] = settings['tpl_cell_attributes'].render(Context(row_dict)) field['settings'] = settings fields_set.append(field) rows.append({'settings': row_settings, 'fields': fields_set}) return render_to_string('reports_widget_table.html', {'fields': fields_visible, 'rows': rows, 'widget_obj': self._widget_obj}) def __call__(self): u'''  ,   ''' try: return self.get_html() except Exception as e: return u'   %s: "%s"' % (self._widget_obj.title, e) 



рдпрд╣ рдбреЗрдЯрд╛ рд╕реНрд░реЛрдд рд╕реЗ рдбреЗрдЯрд╛ рд▓реЗрддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рддрд╛рд▓рд┐рдХрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИред рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ
- рд╕реНрд╡рд░реВрдкрдг
- рд▓рд┐рдВрдХ рдХреА рдкреАрдврд╝реА (рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рд╕реА рдЕрдиреНрдп рддрд╛рд▓рд┐рдХрд╛, рдЧреНрд░рд╛рдлрд╝ рдпрд╛ рдПрдХреНрд╕реЗрд▓ рдореЗрдВ рдХреЛрд╢рд┐рдХрд╛рдУрдВ рдХреЛ рдбреНрд░рд┐рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ)
- рдордирдорд╛рдиреЗ рдврдВрдЧ рд╕реЗ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреА рдЙрддреНрдкрддреНрддрд┐ (рдХрд╛рд░реНрдпрд╢реАрд▓ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд▓рд┐рдП, рдкрд░рд┐рдгрд╛рдореА рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреЛ рдЫрд┐рдкрд╛рдирд╛ рдпрд╛ рджрд┐рдЦрд╛рдирд╛ рдЖрджрд┐ред

рд░рд┐рдкреЛрд░реНрдЯ рдкреНрд░рдмрдВрдзрдХ
 class ReportManager(object): u'''   ''' def __init__(self, request, report): self._report = report self._request = request self._user = request.user self._forms = {} self._env = EnvirementManager(request=request, user_params=self._get_user_params(), forms={}, f={}) self._datasets = {} self._widgets_table = {} self._widgets_chart = {} self._load_stored_filter_values() #   for filter_obj in self._report.forms.only('title', 'html_layout'): filter_manager = FilterManager(self._request, filter_obj, self._env) self._save_stored_filter_values(filter_manager.get_changed_data()) self._forms[filter_obj.title] = filter_manager self._env['forms'] = self._forms #    for ds in self._report.datasets.only('sql', 'title', 'xml_settings'): self._datasets[ds.title] = DatasetManager(request, ds, self._env) self._env['datasets'] = self._datasets #  - for widget_obj in self._report.widgets_table.only('title', 'dataset', 'table_header', 'xml_settings'): self._widgets_table[widget_obj.title] = WidgetTableManager(self._request, widget_obj, self._datasets[widget_obj.dataset.title], self._env) self._env['tables'] = self._widgets_table #  -  for chart_obj in self._report.widgets_chart.only('title', 'dataset', 'xml_settings'): self._widgets_chart[chart_obj.title] = WidgetChartManager(self._request, chart_obj, self._datasets[chart_obj.dataset.title], self._env) self._env['charts'] = self._widgets_chart def get_request(self): u'''   ''' response_type = self._request.REQUEST.get('response_type', 'html') if response_type == 'xls': return self._get_request_xls(self._request.REQUEST['xls']) elif response_type == 'template': return self._get_request_template(self._request.REQUEST['template']) else: return self._get_request_html() def _get_request_html(self): u'''     html     ''' context = {'favorite_reports': self._user.reports_favorited.all()} context['report_body'] = self._env.render(self._report.html_layout) context['breadcrumbs'] = (('', reverse('reports_home')), (self._report.title, None)) context['filter_presets'] = self._report.filter_presets.filter(user=self._user) context['report'] = self._report return render(self._request, 'reports_report.html', context) def _get_request_template(self): u'''     html     ''' # TODO raise NotImplementedError(u' ') def _get_request_xls(self, dataset_title): u"""     xls """ dataset = self._datasets[dataset_title] (columns, data) = dataset.get_data() w = Workbook(optimized_write=True) sheet = w.create_sheet(0) sheet.append(columns) rows_in_sheet = 0 for row in data: if rows_in_sheet > 1000000: sheet = w.create_sheet() sheet.append(columns) rows_in_sheet = 0 sheet.append(row) rows_in_sheet += 1 try: tmpFileName = os.tempnam() w.save(tmpFileName) fh = open(tmpFileName, 'rb') resp = HttpResponse(fh.read(), 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') finally: if fh: fh.close() os.unlink(tmpFileName) resp['Content-Disposition'] = 'attachment; filename=".xlsx"' return resp def _get_request_document_template(self, template_title): u"""  ,     """ pass def _save_stored_filter_values(self, values): u"""        _env    html,      ,             """ for key, value in values.items(): self._env['f'][key] = value if values.get('response_type', 'html') == 'html': (store_item, is_created) = models.WidgetFormStorage.objects.get_or_create(user=self._user, report=self._report, key=key) store_item.value = pickle.dumps(value) store_item.save() def _load_stored_filter_values(self): u"""   ,      """ for item in self._report.form_storage.all(): self._env['f'][item.key] = pickle.loads(item.value) def _get_user_params(self): u"""    """ params = {} try: param_string = models.UserAccess.objects.get(report=self._report, user=self._user).params if param_string: for pair in param_string.split(';'): (key, values_str) = pair.split('=') values = values_str.split(',') params[key] = values except Exception, e: pass return params 



рдХреЗрд╡рд▓ рдПрдХ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рд╡рд┐рдзрд┐ рд╣реИ рдЬреЛ httpResponse (html, рдЕрдиреБрд▓рдЧреНрдирдХ, рдпрд╛ xlsx) рд▓реМрдЯрд╛рддреА рд╣реИ

рдпрд╣ рдореВрд▓ рд░реВрдк рд╕реЗ рд╕рднреА рд╣реИред
рд╡реНрдпрд╡рд╕реНрдерд╛рдкрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХрд╛ рд╡рд░реНрдгрди рдирд╣реАрдВ рдХрд┐рдпрд╛ред

рдмреВрдЯрд╕реНрдЯреНрд░реИрдк рд╕реЗ рд╕реАрдПрд╕рдПрд╕

рдХреБрдЫ рдЕрднреНрдпрд╛рд╕ рдФрд░ рдЪрд┐рддреНрд░



рдбреА рдПрд╕ рдбреЗрдЯрд╛ рд╕реНрд░реЛрдд
 select key, value, value * 0.5 as value1 from ( select 1 as key, 2000 as value union all select 2 as key, 4000 as value union all select 3 as key, 6000 as value union all select 4 as key, 3000 as value union all select 5 as key, 2000 as value union all select 6 as key, 1000 as value ) t {% if f.doble_rows %}cross join (select 1 union all select 2) t1 {% endif %} 



Ds1 рдбреЗрдЯрд╛ рд╕реНрд░реЛрдд
 select t.key as key, t.value as value, case when key = 1 then 'background-color: #dff0d8;' end as row_style_field, case when key = 2 then 'class="error"' end as row_attribute_field {% if f.add_column %} {% for row in datasets.ds.data %} , {{row.key}} as {{row.key}} {% endfor %} {% endif %} from ({{datasets.ds.sql}}) t {% if request.GET.key %} where key = [[request.GET.key]] {% endif %} {% if f.limit %} limit [[f.limit]] {% endif %} 



рдЯреЗрдмрд▓ рд╡рд┐рдЬреЗрдЯ рдЯреА:
рд╕реВрдЪреА рд╕реЗ ds1 рд╕реНрд░реЛрдд рдХрд╛ рдЪрдпрди рдХрд░рдХреЗ рдмрдирд╛рдПрдБ
рдФрд░ рдирд╛рдо рдХреА рд╡рд░реНрддрдиреАред рд╣рдо рдмрд╛рдХреА рдХреЛ рдирд╣реАрдВ рдЫреВрддреЗ рд╣реИрдВред

рддрд╛рд▓рд┐рдХрд╛ t1 (ds1 рдкрд░)
 <xml> <table field_row_style='row_style_field' field_row_attributes='row_attribute_field'/> <fields> <field name='' classes='text-right'/> <field name='value' classes='text-right' lnk='?response_type=xls&xls=ds&key=[[row.]]&from=value'/> {% for row in datasets.ds.data %} <field name='{{row.key}}' classes='text-right' lnk='?response_type=xls&xls=ds1&key=[[row.]]&from={{row.key}}'/> {% endfor %} <field name='1' display='0'/> <field name='row_style_field' display='0'/> <field name='row_attribute_field' display='0'/> </fields> </xml> 



рддрд╛рд▓рд┐рдХрд╛ t1 (ds1 рдкрд░)
 <xml> <table field_row_style='row_style_field' field_row_attributes='row_attribute_field'/> <fields> <field name='' classes='text-right'/> <field name='value' classes='text-right' lnk='?response_type=xls&xls=ds&key=[[row.]]&from=value'/> {% for row in datasets.ds.data %} <field name='{{row.key}}' classes='text-right' lnk='?response_type=xls&xls=ds1&key=[[row.]]&from={{row.key}}'/> {% endfor %} <field name='1' display='0'/> <field name='row_style_field' display='0'/> <field name='row_attribute_field' display='0'/> </fields> </xml> 



рдЧреНрд░рд╛рдл рдкрд░реАрдХреНрд╖рдг (рдбреАрдПрд╕ рдкрд░)
 <xml> <chart> <categoryField>key</categoryField> <marginTop>32</marginTop> </chart> <categoryAxis> <labelsEnabled>true</labelsEnabled> <gridCount>50</gridCount> <equalSpacing>true</equalSpacing> </categoryAxis> <valueAxis> <valueAxisLeft> <stackType>regular</stackType> <gridAlpha>0.07</gridAlpha> </valueAxisLeft> </valueAxis> <cursor> <bulletsEnabled>true</bulletsEnabled> </cursor> <graphs> <graph> <type>column</type> <title></title> <valueField>value</valueField> <balloonText>[[category]] : [[value]] .</balloonText> <lineAlpha>0</lineAlpha> <fillAlphas>0.6</fillAlphas> </graph> <graph1> <type>column</type> <title> </title> <valueField>value1</valueField> <balloonText>[[category]] : [[value]] .</balloonText> <lineAlpha>0</lineAlpha> <fillAlphas>0.6</fillAlphas> </graph1> </graphs> </xml> 



рдЧреНрд░рд╛рдл рдЯреЗрд╕реНрдЯ 1 (рдбреАрдПрд╕ рдкрд░)
 <xml> <chart> <categoryField>key</categoryField> <marginTop>32</marginTop> </chart> <categoryAxis> <labelsEnabled>true</labelsEnabled> <gridCount>50</gridCount> <equalSpacing>true</equalSpacing> </categoryAxis> <valueAxis> <valueAxisLeft> <gridAlpha>0.07</gridAlpha> </valueAxisLeft> </valueAxis> <cursor> <bulletsEnabled>true</bulletsEnabled> </cursor> <graphs> <graph> <type>column</type> <title></title> <valueField>value</valueField> <balloonText>[[category]] : [[value]] .</balloonText> <lineAlpha>0</lineAlpha> <fillAlphas>0.6</fillAlphas> </graph> <graph1> <type>column</type> <title> </title> <valueField>value1</valueField> <balloonText>[[category]] : [[value]] .</balloonText> <lineAlpha>0</lineAlpha> <fillAlphas>0.6</fillAlphas> </graph1> <graph2> <type>smoothedLine</type> <title> </title> <valueField>value1</valueField> </graph2> </graphs> </xml> 



рд╣рдо рд╕реНрдХреНрд░реАрди рдкрд░ рдЬрдЧрд╣ рджреЗрддреЗ рд╣реИрдВ
 <h2>   </h2> <div class='well well-small'>{{forms.f}}</div> <h3> - django template</h3> <pre> sql:{{datasets.ds1.render.sql}} :{{datasets.ds1.render.binds}} </pre> <h3> </h3> {{tables.t}} <a class='btn btn-success' href='?response_type=xls&xls=ds1'> Excel</a> <h2> </h2> {{tables.t1}} <div style='height:500px;width:500px;'>{{charts.test}}</div> <div style='height:500px;width:500px;'>{{charts.test1}}</div> 



рд╡реНрдпрд╡рд╕реНрдерд╛рдкрдХ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ



рд╡рд╣реА рд╣реБрдЖ
рд░рд┐рдкреЛрд░реНрдЯ рдХреА рд╕реВрдЪреА:


рд╣рдорд╛рд░реА рд░рд┐рдкреЛрд░реНрдЯ:



рдореИрдВ рдкрд╛рд╡реЗрд▓, рдЕрд▓реЗрдХреНрдЬреЗрдВрдбрд░, рдпреВрдЬреАрди рдХреА рдорджрдж рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж рдХрд╣рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред
рдЖрдкрдХрд╛ рдзреНрдпрд╛рди рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред рдпрджрд┐ рдЖрдк рдЪрд╛рд╣реЗрдВ, рддреЛ рдЖрдк рдЗрд╕реЗ рднрдВрдбрд╛рд░ рд╕реЗ рд▓реЗ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЕрдкрдиреА рдЗрдЪреНрдЫрд╛рдиреБрд╕рд╛рд░ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
bitbucket.org/dibrovsd/py_docflow

рдкреАрдПрд╕ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рдЕрднреА рднреА рдПрдХ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд░реВрдк рд╕реЗ рдкреВрд░рд╛ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╡рд░реНрдХрдлрд╝реНрд▓реЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╣реИ,
рд▓реЗрдХрд┐рди рдЙрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдереЛрдбрд╝реА рджреЗрд░ рдмрд╛рдж, рдЕрдЧрд░ рдпрд╣ рдЖрдкрдХреЗ рд▓рд┐рдП рджрд┐рд▓рдЪрд╕реНрдк рд╣реЛрдЧрд╛ред

рдкреА рдкреА рдПрд╕
рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдХрдИ рдЧреИрд░-рдЗрд╖реНрдЯрддрдо рд╕рдорд╛рдзрд╛рди рд╣реИрдВ, рдореИрдВ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдЕрдЬрдЧрд░ рдФрд░ django рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рд╣реВрдВред
рдХреГрдкрдпрд╛ рд╡реНрдпрдХреНрддрд┐рдЧрдд рдореЗрдВ рд╕рднреА рд░рдЪрдирд╛рддреНрдордХ рд╕реБрдЭрд╛рд╡ рд▓рд┐рдЦреЗрдВред

Source: https://habr.com/ru/post/In177567/


All Articles