Skip to content
Advertisement

API Project: AttributeError: ‘list’ object has no attribute ‘id’

This is my first time working with Python and APIs. I am trying to get a list of books based on an author’s name. I’m using SQLAlchemy for this and Python 3.10.2. I think this is all the relevant code:

class Author(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100))
    biography = db.Column(db.String(100))
    publisher = db.Column(db.String(50))

    def __init__(self,name,biography,publisher):
        self.name = name
        self.biography = biography
        self.publisher = publisher

# FUNCTION TO RETURN AN AUTHOR DICTIONARY
def author_dict(new_author):
    author = {
        "id": new_author.id,
        "name": new_author.name,
        "biography": new_author.biography,
        "publisher": new_author.publisher
    }
    return author

# GET A LIST OF BOOKS BASED ON AUTHOR
@app.route('/bookauthor/<name>', methods = ['GET'])
def book_author(name):
    author = Author.query.filter_by(name=name).all()
    authorFilter = author_dict(author)
    return json.dumps(authorFilter)

Why am I getting this error:

AttributeError: 'list' object has no attribute 'id'

And how do I fix it?

Advertisement

Answer

The all() method will return you a list of Author instances.

You cannot call the author_dict by passing a list of Author instances. This function accept only one Author instance. But you can achieve what you are looking for with a simple list comprehension

@app.route('/bookauthor/<name>', methods = ['GET'])
def book_author(name):
    authors = Author.query.filter_by(name=name).all()
    authorFilter = [author_dict(author) for author in authors]
    return json.dumps(authorFilter)

Another “cleaner” way is to create a to_dict method at the Author class level :

class Author(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100))
    biography = db.Column(db.String(100))
    publisher = db.Column(db.String(50))

    def __init__(self,name,biography,publisher):
        self.name = name
        self.biography = biography
        self.publisher = publisher
   
    def to_dict():
        return {
        "id": new_author.id,
        "name": new_author.name,
        "biography": new_author.biography,
        "publisher": new_author.publisher
        }


# GET A LIST OF BOOKS BASED ON AUTHOR
@app.route('/bookauthor/<name>', methods = ['GET'])
def book_author(name):
    authors = Author.query.filter_by(name=name).all()
    return json.dumps([author.to_dict() for author in authors])
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement