<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
  <channel>
    <atom:link rel="self" type="application/rss+xml" href="http://breys.ru/rss"/>
    <language>ru</language>
    <copyright>Copyright 2008,2009 breys.ru</copyright>
    <title>Заметки на breys.ru</title>
    <link>http://breys.ru/blog/</link>
    <description>Заметки по теме: Flask, Брейс - дизайн студия</description>
    <item>
      <link>http://breys.ru/blog/1618.html</link>
      <guid>http://breys.ru/blog/1618.html</guid>
      <title>Flask restful сериализация sqlalchemy моделей в Json поток</title>
      <pubDate>Sun, 19 Apr 2015 16:25:06 +0400</pubDate>
      <description>&lt;p&gt;При использовать в проекте flask-restful удобно и необходимо возвращать в качестве результатов запросов объекты формируемые sqlalchemy моделями. Но есть одна проблема, так как очень часто эти модели содержат слишком много всяких дополнительных свойств, то встроенный сериализатор не справляется и ругается словами&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;is&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;not&lt;/span&gt;&lt;span&gt; JSON serializable&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Проблема решается путём переопределения встроенного сериализатора Flask, а делается это вот так:&lt;/p&gt;
&lt;p&gt;среди атрибутов приложения есть свойство указывающее на класс сериализатора Json, нам остаётся лишь взять базовый класс, переопределить его возможности обработкой своих типов и передать на исполнение в приложение (ниже общая схема)&lt;/p&gt;
&lt;pre&gt;&lt;p&gt;from flask.json import JSONEncoder&lt;/p&gt;class CustomJSONEncoder(JSONEncoder):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def default(self, obj):&lt;br /&gt;      # обработка собственных типов&lt;br /&gt;      if isinstance(obj, мои типы):&lt;br /&gt;         ....&lt;br /&gt;      # стандартная обработка&lt;br /&gt;      return JSONEncoder.default(self, obj)&lt;br /&gt;&lt;p&gt;app.json_encoder = CustomJSONEncoder
&lt;/p&gt;&lt;/pre&gt;
&lt;p&gt;Чтобы научить сериализатор обрабатывать объекты sqlalchemy необходимо использовать следующую конструкцию&lt;/p&gt;
&lt;pre&gt;&lt;p&gt;from sqlalchemy.ext.declarative import DeclarativeMeta&lt;/p&gt;class CustomJSONEncoder(JSONEncoder):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def default(self, obj):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if isinstance(obj.__class__, DeclarativeMeta):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # обрабатываем объект sqlalchemy&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fields = {}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; obj_dict = obj.__dict__&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for field in obj.__table__.columns.keys(): # получаем список полей связанной с моделью таблицы&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; data = obj_dict.get(field) # извлекаем данные по имени поля&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; json.dumps(data)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fields[field] = data&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; except TypeError:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fields[field] = None&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return fields&lt;/p&gt;&lt;p&gt;          return JSONEncoder.default(self, obj)&lt;/p&gt;&lt;/pre&gt;
&lt;p&gt;Собственно метод заключается в преобразование объекта sqlalchemy в обычный словарь, с последующей сериализацией полей словаря, имена которых являются полями таблицы, список которых получаем с помощью метода obj.__table__.columns.keys()&lt;/p&gt;
&lt;p&gt;&lt;a title="открыть: " rel="lightbox[roadtrip]" href="/upload/1429450216.04.png"&gt;&lt;img title="сериализация sqlalchemy моделей " src="/upload/images/1429450216.04.png" alt="сериализация sqlalchemy моделей " /&gt;&lt;/a&gt;&lt;a title="открыть: результат обращения к flask restful api" rel="lightbox[roadtrip]" href="/upload/1429450247.25.png"&gt;&lt;img src="/upload/images/1429450247.25.png" alt="результат обращения к flask restful api" /&gt;&lt;/a&gt;&lt;a title="открыть: пример кода restful кода" rel="lightbox[roadtrip]" href="/upload/1429450302.11.png"&gt;&lt;img src="/upload/images/1429450302.11.png" alt="пример кода restful кода" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Использование такого метода позволяет очень просто и наглядно формировать rest Api с помощью sqlalchemy моделей&lt;/p&gt;
&lt;pre&gt;return jsonify(result=True, id=id, page=model_Page.query.get(id))&lt;/pre&gt;</description>
      <author>ffsdmad@jabber.ru ( Басманов ) </author>
    </item>
    <item>
      <link>http://breys.ru/blog/1612.html</link>
      <guid>http://breys.ru/blog/1612.html</guid>
      <title>Отключаем csrt проверку во Flask</title>
      <pubDate>Thu, 11 Sep 2014 13:41:15 +0400</pubDate>
      <description>&lt;p&gt;При отладке механизм защиты сайта csrt_token очень затрудняет жизнь, для его отключения, а лучше всего для управления этим механизмом нужно в config.py внести переменную&lt;/p&gt;
&lt;pre&gt;CSRF_ENABLED = True&lt;/pre&gt;
&lt;p&gt;Затем в __init__.py главного модуля добавить такие строки&lt;/p&gt;
&lt;pre&gt;if app.config[&amp;#039CSRF_ENABLED&amp;#039]:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; from flask_wtf.csrf import CsrfProtect&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CsrfProtect().init_app(app)&lt;/pre&gt;
&lt;p&gt;Затем при использовании форм передавать им дополнительный параметр&lt;/p&gt;
&lt;pre&gt;form = CreateProduct(csrf_enabled=app.config[&amp;#039CSRF_ENABLED&amp;#039])&lt;/pre&gt;
&lt;p&gt;Ну и на последок, в шаблонах, использовать вот такую конструкцию&lt;/p&gt;
&lt;pre&gt;{% if csrf_token %}{{ csrf_token() }}{% endif %}&lt;/pre&gt;
&lt;p&gt;таким образом изменяя состояние CSRF_ENABLED в конфиге вы будете контолировать этот параметр по всему проекту&lt;/p&gt;</description>
      <author>ffsdmad@jabber.ru ( Басманов ) </author>
    </item>
  </channel>
</rss>

