question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

How to override model creation form?

See original GitHub issue

Hi, I’d like to override flask-admin’s model creation form. So I override form object like below.

from wtforms import PasswordField, StringField, form, Form
from wtforms.validators import DataRequired, Length, EqualTo
from wtforms.ext.sqlalchemy.fields import QuerySelectField
from flask.ext.admin.contrib.sqla import ModelView

class ShopOwnerForm(form.Form):
    name = StringField(
        'Username',
        validators=[
            DataRequired(),
            Length(max=128),
        ],
    )
    shop = QuerySelectField(
        'Shop Name',
        query_factory=Shop.query.all,
        get_pk=attrgetter('id'),
        get_label=attrgetter('name'),
    )

class ShopOwnerAdmin(ModelView):
    form = ShopOwnerForm

But, sqlalchemy.exc.InvalidRequestError has occured at following point.

https://github.com/flask-admin/flask-admin/blob/master/flask_admin/contrib/sqla/view.py#L1014

This is the error message .

Traceback (most recent call last):
  File "/Users/zakuro/src/gitlab.com/akashipy/guji_delivery/venv/lib/python3.5/site-packages/flask/app.py", line 1836, in __call__
    return self.wsgi_app(environ, start_response)
  File "/Users/zakuro/src/gitlab.com/akashipy/guji_delivery/venv/lib/python3.5/site-packages/flask/app.py", line 1820, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "/Users/zakuro/src/gitlab.com/akashipy/guji_delivery/venv/lib/python3.5/site-packages/flask/app.py", line 1403, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/zakuro/src/gitlab.com/akashipy/guji_delivery/venv/lib/python3.5/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/Users/zakuro/src/gitlab.com/akashipy/guji_delivery/venv/lib/python3.5/site-packages/flask/app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "/Users/zakuro/src/gitlab.com/akashipy/guji_delivery/venv/lib/python3.5/site-packages/flask/app.py", line 1477, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/Users/zakuro/src/gitlab.com/akashipy/guji_delivery/venv/lib/python3.5/site-packages/flask/app.py", line 1381, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/zakuro/src/gitlab.com/akashipy/guji_delivery/venv/lib/python3.5/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/Users/zakuro/src/gitlab.com/akashipy/guji_delivery/venv/lib/python3.5/site-packages/flask/app.py", line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File "/Users/zakuro/src/gitlab.com/akashipy/guji_delivery/venv/lib/python3.5/site-packages/flask/app.py", line 1461, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/Users/zakuro/src/gitlab.com/akashipy/guji_delivery/venv/lib/python3.5/site-packages/flask_admin/base.py", line 68, in inner
    return self._run_view(f, *args, **kwargs)
  File "/Users/zakuro/src/gitlab.com/akashipy/guji_delivery/venv/lib/python3.5/site-packages/flask_admin/base.py", line 367, in _run_view
    return fn(self, *args, **kwargs)
  File "/Users/zakuro/src/gitlab.com/akashipy/guji_delivery/venv/lib/python3.5/site-packages/flask_admin/model/base.py", line 1834, in create_view
    model = self.create_model(form)
  File "/Users/zakuro/src/gitlab.com/akashipy/guji_delivery/venv/lib/python3.5/site-packages/flask_admin/contrib/sqla/view.py", line 1031, in create_model
    if not self.handle_view_exception(ex):
  File "/Users/zakuro/src/gitlab.com/akashipy/guji_delivery/venv/lib/python3.5/site-packages/flask_admin/contrib/sqla/view.py", line 1014, in handle_view_exception
    return super(ModelView, self).handle_view_exception(exc)
  File "/Users/zakuro/src/gitlab.com/akashipy/guji_delivery/venv/lib/python3.5/site-packages/flask_admin/contrib/sqla/view.py", line 1027, in create_model
    self.session.add(model)
  File "/Users/zakuro/src/gitlab.com/akashipy/guji_delivery/venv/lib/python3.5/site-packages/sqlalchemy/orm/scoping.py", line 150, in do
    return getattr(self.registry(), name)(*args, **kwargs)
  File "/Users/zakuro/src/gitlab.com/akashipy/guji_delivery/venv/lib/python3.5/site-packages/sqlalchemy/orm/session.py", line 1600, in add
    self._save_or_update_state(state)
  File "/Users/zakuro/src/gitlab.com/akashipy/guji_delivery/venv/lib/python3.5/site-packages/sqlalchemy/orm/session.py", line 1612, in _save_or_update_state
    self._save_or_update_impl(state)
  File "/Users/zakuro/src/gitlab.com/akashipy/guji_delivery/venv/lib/python3.5/site-packages/sqlalchemy/orm/session.py", line 1867, in _save_or_update_impl
    self._save_impl(state)
  File "/Users/zakuro/src/gitlab.com/akashipy/guji_delivery/venv/lib/python3.5/site-packages/sqlalchemy/orm/session.py", line 1835, in _save_impl
    self._before_attach(state)
  File "/Users/zakuro/src/gitlab.com/akashipy/guji_delivery/venv/lib/python3.5/site-packages/sqlalchemy/orm/session.py", line 1956, in _before_attach
    state.session_id, self.hash_key))
sqlalchemy.exc.InvalidRequestError: Object '<ShopOwner at 0x110d3af98>' is already attached to session '1' (this is '7')

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:8 (4 by maintainers)

github_iconTop GitHub Comments

8reactions
xqliucommented, Apr 25, 2016

I think you can just try to override the create_form or edit_form method from ModelView as below:

    def create_form(self, obj=None):
        form = super(ModelView, self).create_form(obj)
        # Do what you would like to do
        form.code.data = Product.get_next_code() #Set up value of a field
        form_util.filter_by_organization(form.category, ProductCategory) #Apply filter
        if not is_super_admin(): # Delete a field from UI.
            delattr(form, "organization")
        return form

You may also override scaffold_form method as below which will applies to both create an edit form.

    def scaffold_form(self):
        # Start with the standard form as provided by Flask-Admin. We've already told Flask-Admin to exclude the
        # password field from this form.
        form = super(UserAdmin, self).scaffold_form()

        # Add a password field, naming it "password2" and labeling it "New Password".
        form.password2 = PasswordField(label=lazy_gettext('New Password'),
                                             description=lazy_gettext('Left blank if you don\'t want to change it, '
                                                                      'input the new password to change it'))
        return form

Hope the above information helps you.

2reactions
panosangelopouloscommented, Mar 31, 2016

Try the following example and keep us update if it works. If everything works fine then try to add validators and QuerySelectField.

from flask_admin.contrib.sqla import ModelView

class ShopOwnerForm(Form):
    name = StringField('Username')

class ShopOwnerAdmin(ModelView):
    form = ShopOwnerForm
Read more comments on GitHub >

github_iconTop Results From Across the Web

Creating forms from models - Django documentation
Finally, note that you can override the form field used for a given model field. See Overriding the default fields below.
Read more >
How to Override or Hide Django admin model form field value
method and the answer is: I need the grupo field, but this field must be persisted in DB. It only exists in Cognito....
Read more >
Overriding the save method - Django Models - GeeksforGeeks
Enter the following code into models.py file of geeks app. We will be using CharField for experimenting for all field options. We will...
Read more >
3. How to override save behaviour for Django admin?
ModelAdmin has a save_model method, which is used for creating and updating model objects. By overriding this, you can customize the save behaviour...
Read more >
How to override the save method in your Django models
The Django ORM ensures that whenever an object of a database model is created or updated either via the admin interface or somewhere...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found