0

PostgresデータベースでSQLAlchemyとflask-adminを使用しています。テーブルフィールドの1つはMACアドレスですので、私はpostgresのmacaddrデータ型を使用しました。注文を変更するか、SQLAlchemyを使用してflask-adminで一意のバリデータを無効にします

MACフィールドは一意であり、無効なMACアドレスを送信するとフラスコ管理フォームに問題が発生します。フォームは次のようになります。

class InstancesView(SecureModelView): 
    column_editable_list = ['mac', 'ipv4', 'dns', 'state'] # inline editing 
    form_args = { 
     'mac': { 
      'validators': [validators.required(), validators.MacAddress()] 
     }, 
     'ipv4': { 
      'validators': [validators.required(), validators.IPAddress()] 
     }, 
     'dns': { 
      'validators': [validators.required()] 
     }, 
     'state': { 
      'validators': [validators.required()] 
     } 
    } 

固有のバリデーターはflask-adminに実装されています。自動的に追加され、MACAddressバリデータのようにフィールドに追加するバリデータの前に実行されます。これにより、psycopg2のDataErrorが発生します。唯一のバリデーターは無効なMAC値を取得し、データベースのselectに使用するように見えます。

私にとって最善の解決策は、固有のバリデータの前にMACAddressバリデータを実行しているようです。バリデータの順序を変更する可能性はありますか?あるいは、フラスコ管理者のバリデータの前に関数を実行するのでしょうか?

あなたは完全な誤り見ることができます下:フラスコ管理者からのユニークなバリデータが常に望ましいと(それがさえWTFormsから削除された)、部分的に欠陥があるが、常に接続されていないようですので

[2017-08-02 10:39:43,649] ERROR in app: Exception on /admin/instances/new/ [POST] 
Traceback (most recent call last): 
    File "/home/user/.virtualenvs/flask-gateway/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1182, in _execute_context 
    context) 
    File "/home/user/.virtualenvs/flask-gateway/lib/python3.6/site-packages/sqlalchemy/engine/default.py", line 470, in do_execute 
    cursor.execute(statement, parameters) 
psycopg2.DataError: invalid input syntax for type macaddr: "00:ad:qw:ew:00:00" 
LINE 3: WHERE instances.mac = '00:ad:qw:ew:00:00' 
          ^


The above exception was the direct cause of the following exception: 

Traceback (most recent call last): 
    File "/home/user/.virtualenvs/flask-gateway/lib/python3.6/site-packages/flask/app.py", line 1982, in wsgi_app 
    response = self.full_dispatch_request() 
    File "/home/user/.virtualenvs/flask-gateway/lib/python3.6/site-packages/flask/app.py", line 1614, in full_dispatch_request 
    rv = self.handle_user_exception(e) 
    File "/home/user/.virtualenvs/flask-gateway/lib/python3.6/site-packages/flask/app.py", line 1517, in handle_user_exception 
    reraise(exc_type, exc_value, tb) 
    File "/home/user/.virtualenvs/flask-gateway/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise 
    raise value 
    File "/home/user/.virtualenvs/flask-gateway/lib/python3.6/site-packages/flask/app.py", line 1612, in full_dispatch_request 
    rv = self.dispatch_request() 
    File "/home/user/.virtualenvs/flask-gateway/lib/python3.6/site-packages/flask/app.py", line 1598, in dispatch_request 
    return self.view_functions[rule.endpoint](**req.view_args) 
    File "/home/user/.virtualenvs/flask-gateway/lib/python3.6/site-packages/flask_admin/base.py", line 69, in inner 
    return self._run_view(f, *args, **kwargs) 
    File "/home/user/.virtualenvs/flask-gateway/lib/python3.6/site-packages/flask_admin/base.py", line 368, in _run_view 
    return fn(self, *args, **kwargs) 
    File "/home/user/.virtualenvs/flask-gateway/lib/python3.6/site-packages/flask_admin/model/base.py", line 1994, in create_view 
    if self.validate_form(form): 
    File "/home/user/.virtualenvs/flask-gateway/lib/python3.6/site-packages/flask_admin/model/base.py", line 1334, in validate_form 
    return validate_form_on_submit(form) 
    File "/home/user/.virtualenvs/flask-gateway/lib/python3.6/site-packages/flask_admin/helpers.py", line 65, in validate_form_on_submit 
    return is_form_submitted() and form.validate() 
    File "/home/user/.virtualenvs/flask-gateway/lib/python3.6/site-packages/wtforms/form.py", line 310, in validate 
    return super(Form, self).validate(extra) 
    File "/home/user/.virtualenvs/flask-gateway/lib/python3.6/site-packages/wtforms/form.py", line 152, in validate 
    if not field.validate(self, extra): 
    File "/home/user/.virtualenvs/flask-gateway/lib/python3.6/site-packages/wtforms/fields/core.py", line 204, in validate 
    stop_validation = self._run_validation_chain(form, chain) 
    File "/home/user/.virtualenvs/flask-gateway/lib/python3.6/site-packages/wtforms/fields/core.py", line 224, in _run_validation_chain 
    validator(form, self) 
    File "/home/user/.virtualenvs/flask-gateway/lib/python3.6/site-packages/flask_admin/contrib/sqla/validators.py", line 37, in __call__ 
    .filter(self.column == field.data) 
    File "/home/user/.virtualenvs/flask-gateway/lib/python3.6/site-packages/sqlalchemy/orm/query.py", line 2814, in one 
    ret = self.one_or_none() 
    File "/home/user/.virtualenvs/flask-gateway/lib/python3.6/site-packages/sqlalchemy/orm/query.py", line 2784, in one_or_none 
    ret = list(self) 
    File "/home/user/.virtualenvs/flask-gateway/lib/python3.6/site-packages/sqlalchemy/orm/query.py", line 2855, in __iter__ 
    return self._execute_and_instances(context) 
    File "/home/user/.virtualenvs/flask-gateway/lib/python3.6/site-packages/sqlalchemy/orm/query.py", line 2878, in _execute_and_instances 
    result = conn.execute(querycontext.statement, self._params) 
    File "/home/user/.virtualenvs/flask-gateway/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 945, in execute 
    return meth(self, multiparams, params) 
    File "/home/user/.virtualenvs/flask-gateway/lib/python3.6/site-packages/sqlalchemy/sql/elements.py", line 263, in _execute_on_connection 
    return connection._execute_clauseelement(self, multiparams, params) 
    File "/home/user/.virtualenvs/flask-gateway/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1053, in _execute_clauseelement 
    compiled_sql, distilled_params 
    File "/home/user/.virtualenvs/flask-gateway/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1189, in _execute_context 
    context) 
    File "/home/user/.virtualenvs/flask-gateway/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1402, in _handle_dbapi_exception 
    exc_info 
    File "/home/user/.virtualenvs/flask-gateway/lib/python3.6/site-packages/sqlalchemy/util/compat.py", line 203, in raise_from_cause 
    reraise(type(exception), exception, tb=exc_tb, cause=cause) 
    File "/home/user/.virtualenvs/flask-gateway/lib/python3.6/site-packages/sqlalchemy/util/compat.py", line 186, in reraise 
    raise value.with_traceback(tb) 
    File "/home/user/.virtualenvs/flask-gateway/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1182, in _execute_context 
    context) 
    File "/home/user/.virtualenvs/flask-gateway/lib/python3.6/site-packages/sqlalchemy/engine/default.py", line 470, in do_execute 
    cursor.execute(statement, parameters) 
sqlalchemy.exc.DataError: (psycopg2.DataError) invalid input syntax for type macaddr: "00:ad:qw:ew:00:00" 
LINE 3: WHERE instances.mac = '00:ad:qw:ew:00:00' 
          ^
[SQL: 'SELECT instances.id AS instances_id, instances.mac AS instances_mac, instances.ipv4 AS instances_ipv4, instances.dns AS instances_dns, instances.state AS instances_state \nFROM instances \nWHERE instances.mac = %(mac_1)s'] [parameters: {'mac_1': '00:ad:qw:ew:00:00'}] 
127.0.0.1 - - [02/Aug/2017 10:39:43] "POST /admin/instances/new/?url=%2Fadmin%2Finstances%2F HTTP/1.1" 500 - 

答えて

0

を、I適切なトラッカーに問題を掲載しました。また、以下で説明する追加のフィールドを使用して回避策を作成しました。

editから標準MACフィールドを削除し、ビューを作成し、カスタムフィールドを追加し、フォーム上のフィールドの順序を指定します。

class InstancesView(SecureModelView): 

    # columns excluded from create and edit view 
    form_excluded_columns = ['mac', ] 
    # extra columns in create and edit view 
    form_extra_fields = { 
     'mac2': StringField('Mac Address', validators=[validators.required(), validators.mac_address()]) 
    } 
    # column order in create view 
    form_create_rules = ('mac2', 'ipv4', 'dns', 'state') 
    # column order in edit view 
    form_edit_rules = ('mac2', 'ipv4', 'dns', 'state') 

今すぐカスタムフィールドは、時に編集中の現在のMACを使用して手動で事前に入力する必要がありますビュー:フォームで

def on_form_prefill(self, form, id): 
    form.mac2.data = self.session.query(Instances).filter(Instances.id == id).one().mac 

提出し、新たなフィールドからのデータは、元のMACフィールドに供給されなければならない:

def on_model_change(self, form, model, is_created): 

    if len(model.mac2): 
     model.mac = model.mac2 
関連する問題