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])