[FIXED] Flask-restful AttributeError: type object 'Project' has no attribute 'as_view'

Issue

So im still learning about the structure in flask it seems flask give a too much flexibilty which is kinda confusing for me to decide, so im trying to add my Resource class to the API with the current structure

api
  /__init__.py
  /project.py
models
  /project_management.py
configs.py
configs.json
run.py

but it return error when running
AttributeError: type object ‘Project’ has no attribute ‘as_view’

Traceback (most recent call last):

File "e:\project-py\run.py", line 6, in
from api import * File "e:\project-py\api_init_.py", line 9, in
from .project import * File "e:\project-py\api\project.py", line 6, in
@api.add_resource(Project, ‘/v1/project’) File "C:\Users\rokie\Anaconda3\envs\py39-rest-flask\lib\site-packages\flask_restful_init_.py",
line 391, in add_resource
self.register_view(self.app, resource, *urls, **kwargs) File "C:\Users\rokie\Anaconda3\envs\py39-rest-flask\lib\site-packages\flask_restful_init.py",
line 431, in _register_view
resource_func = self.output(resource.as_view(endpoint, *resource_class_args, AttributeError: type object ‘Project’ has no attribute ‘as_view’

My run.py

from functools import wraps
from flask import Flask, session, g, render_template, flash
# from flask_cors import CORS, cross_origin
from flask_wtf.csrf import CSRFProtect
from pages import *
from api import *

from config import create_app

app = create_app()
app.app_context().push()

# app.register_blueprint(pages)
app.register_blueprint(api, url_prefix='/api')

# app.secret_key = "ff82b98ef8727e388ea8bff063"
csrf = CSRFProtect()
csrf.init_app(app)


if __name__ == "__main__":
    app.run(host='127.0.0.1',debug=True)

Config.py

import json
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
# from flask_wtf.csrf import CSRFProtect
from flask_login import LoginManager
from flask_cors import CORS, cross_origin


db = SQLAlchemy()
ma = Marshmallow()

f = open('configs.json')
config = json.load(f)


def create_app():
    app = Flask(__name__, template_folder='templates')
    app.config['SQLALCHEMY_DATABASE_URI'] = config['config']['database']
    app.config['SECRET_KEY'] = config['config']['secret_key']

    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

    api_v1_cors_config = {
        "origins": ["*"]
    }
    CORS(app, resources={
        r"/api/*": api_v1_cors_config
    })

    db.init_app(app)
    ma.init_app(app)

    login_manager = LoginManager()
    login_manager.login_view = 'pages.login'
    login_manager.init_app(app)

    from models.user_management import User

    @login_manager.user_loader
    def load_user(user_id):
        # since the user_id is just the primary key of our user table, use it in the query for the user
        return User.query.get(int(user_id))
    return app

api init.py folder with the name ‘api’ as the package

from flask import Blueprint
from flask_restful import Api

api_bp=Blueprint('api',__name__)
api = Api(api_bp)

# from .login import *
# from .api_project import *
from .project import *
# from .master_user import *

and lastly the project.py

from . import api
from flask import Flask, jsonify, request
from flask_restful import Resource, Api
from models.project_management import Project, ProjectStatus, Task

@api.add_resource(Project, '/v1/project')
class Project(Resource):
    def get(self):
        try:
            print('test')
            projects = Project.query.all()
            return jsonify({
                'message': 'Data get success',
                'data': projects,
            })
        except Exception as e:
            return jsonify({
                'message': f'failed to get data {e}',
                'data': []
            })

enter code here

Solution

I can’t check it but …

You have the same name Project for model (Project.query.all()) and for class class Project(Resource) and this can make problem.

Because model Project is created (imported) before add_resource() so it uses this model but it has to use class Project

You may have to first define class with different name and later use add_resource() using new class

class MyProject(Resource):
   # ... code ...  

api.add_resource(MyProject, '/v1/project')

Answered By – furas

Answer Checked By – Timothy Miller (Easybugfix Admin)

Leave a Reply

(*) Required, Your email will not be published