Reputation: 772
I'm learning FastAPI on this project and faced the issue - any request no matter GET or POST throws me an error: value is not a valid dict (type=type_error.dict). What is wrong with my code. My models.py
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
telegram_id = Column(Integer, unique=True, index=True)
username = Column(String(50))
pet_name = Column(String(50))
language_code = Column(String(5))
sent_items = relationship("Log", back_populates="recipient")
class Log(Base):
__tablename__ = "sent_log"
id = Column(Integer, primary_key=True, index=True)
user_id = Column(Integer, ForeignKey("users.id"))
recipient = relationship("User", back_populates="sent_items")
article_id = Column(Integer, ForeignKey("articles.id"))
article = relationship("Article", back_populates="items")
class Article(Base):
__tablename__ = "articles"
id = Column(Integer, primary_key=True, index=True)
text = Column(String(1024))
image_url = Column(String(500), index=True)
language_code = Column(String(255))
items = relationship("Log", back_populates="article")
schemas:
class ArticleBase(BaseModel):
text: str
image_url: str
language_code: str
class ArticleCreate(ArticleBase):
pass
class ArticleEdit(ArticleBase):
id: int
class Config:
orm_mode = True
class UserBase(BaseModel):
telegram_id: int
username: str
pet_name: str
language_code: str
class UserCreate(UserBase):
pass
class UserEdit(UserBase):
id: int
class Config:
orm_mode = True
crud.py
def get_articles(db: Session, skip: int = 0, limit: int = 100):
"""Get all articles."""
return db.query(models.Article).offset(skip).limit(limit).all()
def get_article(db: Session, article_id: int):
"""Get article by id."""
return db.query(models.Article).filter(models.Article.id == article_id).first()
def create_article(db: Session, article: schemas.ArticleCreate):
db_article = models.Article(
text=article.text,
image_url=article.image_url,
language_code=article.language_code
)
db.add(db_article)
db.commit()
db.refresh(db_article)
return db_article
main.py
@app.get("/users/{user_telegram_id}", response_model=schemas.UserBase, tags=["user"])
def read_user(user_telegram_id: int, db: Session = Depends(get_db)):
db_user = crud.get_user(db, user_telegram_id=user_telegram_id)
if db_user is None:
raise HTTPException(status_code=404, detail="User not found")
return db_user
@app.post("/articles/", response_model=schemas.ArticleCreate, tags=["article"])
def create_article(article: schemas.ArticleCreate, db: Session = Depends(get_db)):
return crud.create_article(db=db, article=article)
@app.get("/articles/", response_model=schemas.ArticleBase, tags=["article"])
def read_articles(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
items = crud.get_articles(db, skip=skip, limit=limit)
return items
@app.get("/articles/{article_id}", response_model=schemas.ArticleBase, tags=["article"])
def read_article(article_id: int, db: Session = Depends(get_db)):
db_article = crud.get_article(db, article_id=article_id)
if db_article is None:
raise HTTPException(status_code=404, detail="Article not found")
return db_article
By the way, @app.post("/articles/"... throws an error, but also inserts a data in DB.
Upvotes: 3
Views: 11852
Reputation: 772
The problem was here - might to add list[schemas.ArticleBase] for returning multiply items:
@app.get("/articles/", response_model=list[schemas.ArticleBase], tags=["article"])
def read_articles(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
items = crud.get_articles(db, skip=skip, limit=limit)
return items
Upvotes: 2
Reputation: 2699
The problem is in your return, that's why the insertion in the db works.
You want to return the ArticleCreate
schema (response_model=schemas.ArticleCreate
) except that you return your database response directly without any formatting.
So you have to convert your crud response into your schema response.
@app.post("/articles/", response_model=schemas.ArticleCreate, tags=["article"])
def create_article(article: schemas.ArticleCreate, db: Session = Depends(get_db)):
response = crud.create_article(db=db, article=article)
return schemas.ArticleCreate(**response.dict())
or simply use the orm mode inside your ArticleCreate
class
Upvotes: 5