属性错误:'Blog'对象没有属性'items' - FastAPI



我正在尝试使用FastAPI中的PUT操作来更新数据库中的单个记录。但由于某种原因,我一直犯这个错误。除此之外,其他所有操作都可以正常工作。仅为更新查询引发错误。

AttributeError: 'Blog' object has no attribute 'items'

这是相关代码。

def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
class Blog(BaseModel):
title: str
body: str
@app.put('/blog/{id}', status_code=status.HTTP_204_NO_CONTENT, response_class=Response)
def update(id: int, request: schemas.Blog, db: Session = Depends(get_db)):
blog = db.query(models.Blog).filter(models.Blog.id == id)
if not blog.first():
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
detail=f'Blog with id {id} not found')
blog.update(request)
db.commit()

这是StackTrace:

Traceback (most recent call last):
File "c:devfast-tutsenvlibsite-packagesuvicornprotocolshttph11_impl.py", line 396, in run_asgi        
result = await app(self.scope, self.receive, self.send)
File "c:devfast-tutsenvlibsite-packagesuvicornmiddlewareproxy_headers.py", line 45, in __call__        
return await self.app(scope, receive, send)
File "c:devfast-tutsenvlibsite-packagesfastapiapplications.py", line 199, in __call__
await super().__call__(scope, receive, send)
File "c:devfast-tutsenvlibsite-packagesstarletteapplications.py", line 111, in __call__
await self.middleware_stack(scope, receive, send)
File "c:devfast-tutsenvlibsite-packagesstarlettemiddlewareerrors.py", line 181, in __call__
raise exc from None
File "c:devfast-tutsenvlibsite-packagesstarlettemiddlewareerrors.py", line 159, in __call__
await self.app(scope, receive, _send)
File "c:devfast-tutsenvlibsite-packagesstarletteexceptions.py", line 82, in __call__
raise exc from None
File "c:devfast-tutsenvlibsite-packagesstarletteexceptions.py", line 71, in __call__
await self.app(scope, receive, sender)
File "c:devfast-tutsenvlibsite-packagesstarletterouting.py", line 566, in __call__
await route.handle(scope, receive, send)
File "c:devfast-tutsenvlibsite-packagesstarletterouting.py", line 227, in handle
await self.app(scope, receive, send)
File "c:devfast-tutsenvlibsite-packagesstarletterouting.py", line 41, in app
response = await func(request)
File "c:devfast-tutsenvlibsite-packagesfastapirouting.py", line 201, in app
raw_response = await run_endpoint_function(
File "c:devfast-tutsenvlibsite-packagesfastapirouting.py", line 150, in run_endpoint_function
return await run_in_threadpool(dependant.call, **values)
File "c:devfast-tutsenvlibsite-packagesstarletteconcurrency.py", line 34, in run_in_threadpool
return await loop.run_in_executor(None, func, *args)
File "C:Python39libconcurrentfuturesthread.py", line 52, in run
result = self.fn(*self.args, **self.kwargs)
File ".blogmain.py", line 66, in update
blog.update(request)
File "c:devfast-tutsenvlibsite-packagessqlalchemyormquery.py", line 3190, in update
upd = upd.values(values)
File "<string>", line 2, in values
File "c:devfast-tutsenvlibsite-packagessqlalchemysqlbase.py", line 96, in _generative
x = fn(self, *args, **kw)
File "<string>", line 2, in values
File "c:devfast-tutsenvlibsite-packagessqlalchemysqlbase.py", line 125, in check
return fn(self, *args, **kw)
File "c:devfast-tutsenvlibsite-packagessqlalchemysqldml.py", line 701, in values
for k, v in arg.items()
AttributeError: 'Blog' object has no attribute 'items'

这对我很有效…update函数想要更新对象的每个部分,因此必须提到每个部分。我不确定Bitfumes是如何通过单独调用请求对象来管理的。

blog.update({'title': request.title, 'body': request.body})

编辑时间:引用请求字典也有效:

blog.update(request.dict())

我也遇到了同样的问题。然而,我在打印请求后意识到,显示:

"CCD_ 1";

因此,要解决这个问题,只需将您的"请求"转换为字典类型:

dict(request)

试试这个:

@app.put("/blog/update/{id}")
def updateBlog(id, request:schemas.Blog, db:Session=Depends(get_db)):
blog= db.query(model.Blog).filter(model.Blog.id == id).first()

if not blog:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,detail=f'blog with id {id} not found')
else:
db.query(model.Blog).filter(model.Blog.id == id).update(request.dict())
db.commit()
db.refresh(blog)
return blog

您必须迭代博客对象的属性并逐一更新它们。您可以遵循以下示例:https://github.com/tiangolo/full-stack-fastapi-postgresql/blob/master/%7B%7Bcookiecutter.project_slug%7D%7D/backend/app/app/crud/base.py#L49

我也遇到了这个问题。博客不是一个dict,这是一个PydenticBase模型。如果我们检查博客类型,我们在这里得到

<class 'blog.schemas.Blog'>

这不是一个关键对dict,这就是为什么它表明我们没有属性";项目";。只有dict可以保存项和值,所以我们需要将Blog模式转换为dict.

首先,我建议您在schemas.py文件中创建一个新的UpdateBlog

Q.(为什么?为什么不使用现有的博客

A.(因为没有可选[type]字段,所以如果您尝试只更新两个字段中的一个字段(来自主博客类(,那么它将抛出一个错误。这意味着你必须更新所有字段(无论你是否想要(

这里有一个例子:

  • schemas.py文件
from pydantic import BaseModel
from typing import Optional
class Blog(BaseModel):
title: str
body: str
class UpdateBlog(BaseModel):
title: Optional[str]
body: Optional[str]
  • main.py文件
# Update Blog
@app.put('/blog/{id}', status_code=status.HTTP_202_ACCEPTED)
def update(id, request_body: UpdateBlog, db: Session = Depends(get_db)):
blog = db.query(models.Blog).filter(models.Blog.id == id).first()
if not blog:
content={'success': False, 'message': f"Blog with id {id} don't exists"}
return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, content=content)

# exclude_none=True will only update the field which you want to update
# If you don't want to update "body" then only pass the "title" and "body" field will stay as it is
db.query(models.Blog).filter(models.Blog.id == id).update(request_body.dict(exclude_none=True))
db.commit()
content={'success': True, 'message': f"Blog with id {id} Updated"}
return JSONResponse(status_code=status.HTTP_200_OK, content=content)

相关内容

最新更新