Search code examples
pythonflaskflask-admin

AttributeError: type object 'Page' has no attribute 'query'


Trying to add a custom batch action but I keep getting this error, I've added my imports into the code to show what i'm importing, this file is separate to my model file, this is my views.py file

Views.py

import flask_admin as admin
import textwrap
from flask_admin.actions import action
from flask_admin.contrib import sqla
from flask_admin.contrib.sqla import ModelView
from flask_admin.contrib.sqla.filters import FilterEqual
from app.models import FileRegister, FileRegisterStatus
from app import app, db, models


class PageView(ModelView):
    @action("active", "Active", 'Are you sure you want to active selected pages?')
def action_active(self, ids):
    try:
        query = Page.query.filter(Page.id.in_(ids))

        count = 0
        for page in query.all():
            page.is_active = True    
            count += 1

        flash(ngettext('Page was successfully activated.',
                       '%(count)s pages were successfully activated.',
                       count,
                       count=count))
    except Exception as ex:
        if not self.handle_view_exception(ex):
            raise

        flash(gettext('Failed to active pages. %(error)s', error=str(ex)), 'error')

models.py

    from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, Boolean, TIMESTAMP, ForeignKey
import datetime

Base = declarative_base()


class Page(Base):
    __tablename__ = 'page'
    id = Column(Integer, primary_key=True, nullable=False, autoincrement=True)
    page_name= Column(String(500), index=True, nullable=False)
    is_page_active= Column(Boolean())

    def __init__(self, page_name, is_page_active):
        self.page_name= page_name
        self.is_page_active= is_page_active

    def __unicode__(self):
        return self.page_name

This is the Traceback (most recent call last) I get after running the code, ,I think its because I call query() on my mapped classes instead of the session?

   Traceback (most recent call last):
  File "C:\page\env\lib\site-packages\flask\app.py", line 1997, in __call__
    return self.wsgi_app(environ, start_response)
  File "C:\page\env\lib\site-packages\flask\app.py", line 1985, in wsgi_app
    response = self.handle_exception(e)
  File "C:\page\env\lib\site-packages\flask\app.py", line 1540, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "C:\page\env\lib\site-packages\flask\app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "C:\page\env\lib\site-packages\flask\app.py", line 1614, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "C:\page\env\lib\site-packages\flask\app.py", line 1517, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "C:\page\env\lib\site-packages\flask\app.py", line 1612, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:\page\env\lib\site-packages\flask\app.py", line 1598, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "C:\page\flask_admin\base.py", line 69, in inner
    return self._run_view(f, *args, **kwargs)
  File "C:\page\flask_admin\base.py", line 368, in _run_view
    return fn(self, *args, **kwargs)
  File "c:\page\flask_admin\model\base.py", line 2145, in action_view
    return self.handle_action()
  File "C:\page\flask_admin\actions.py", line 117, in handle_action
    response = handler[0](ids)
  File "C:\page\app\views.py", line 28, in action_active
    if not self.handle_view_exception(ex):
  File "c:\page\flask_admin\contrib\sqla\view.py", line 1060, in handle_view_exception
    return super(ModelView, self).handle_view_exception(exc)
  File "C:\page\app\views.py", line 16, in action_active
    query = Page.query.filter(Page.active_ind.in_(ids))
AttributeError: type object 'Page' has no attribute 'query'

Solution

  • Since I was using a declarative model, this was the fix. This goes into the models.py file

    from sqlalchemy import create_engine
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy.orm import scoped_session, sessionmaker    
    
    engine = create_engine('databaselinkgoeshere', convert_unicode=True)
        db_session = scoped_session(sessionmaker(autocommit=False,
                                                 autoflush=False,
                                                 bind=engine))
    
    Base = declarative_base()
    Base.query = db_session.query_property()