Update generated backend for blog_app with entities: posts, comments, tags, user
This commit is contained in:
parent
ddfc65091e
commit
a7697a758c
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
__pycache__\n*.pyc\n*.db\nvenv/\n
|
|
@ -1,24 +1,40 @@
|
|||||||
Here's a `comments.py` file with a SQLAlchemy model for comments, following the FastAPI project structure with SQLite and SQLAlchemy:
|
Here's the `comments.py` file for the `app/api/v1/models/` directory in the `blog_app_igblf` FastAPI backend project, defining a SQLAlchemy model for comments:
|
||||||
|
|
||||||
|
|
||||||
|
from typing import Optional
|
||||||
from sqlalchemy import Column, ForeignKey, Integer, String, Text
|
from sqlalchemy import Column, ForeignKey, Integer, String, Text
|
||||||
from sqlalchemy.orm import relationship
|
from sqlalchemy.orm import relationship
|
||||||
|
from app.db import Base
|
||||||
from app.db.base_class import Base
|
|
||||||
|
|
||||||
class Comment(Base):
|
class Comment(Base):
|
||||||
__tablename__ = "comments"
|
__tablename__ = "comments"
|
||||||
|
|
||||||
id = Column(Integer, primary_key=True, index=True)
|
id = Column(Integer, primary_key=True, index=True)
|
||||||
content = Column(Text, nullable=False)
|
|
||||||
author = Column(String, nullable=False)
|
|
||||||
post_id = Column(Integer, ForeignKey("posts.id"), nullable=False)
|
post_id = Column(Integer, ForeignKey("posts.id"), nullable=False)
|
||||||
|
author_id = Column(Integer, ForeignKey("users.id"), nullable=False)
|
||||||
|
content = Column(Text, nullable=False)
|
||||||
|
created_at = Column(String, nullable=False)
|
||||||
|
updated_at = Column(String, nullable=True)
|
||||||
|
|
||||||
post = relationship("Post", back_populates="comments")
|
post = relationship("Post", back_populates="comments")
|
||||||
|
author = relationship("User", back_populates="comments")
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"Comment(id={self.id}, content='{self.content[:20]}...', author='{self.author}', post_id={self.post_id})"
|
return f"Comment(id={self.id}, post_id={self.post_id}, author_id={self.author_id}, content='{self.content}', created_at='{self.created_at}', updated_at='{self.updated_at}')"
|
||||||
|
|
||||||
Explanation:
|
Explanation:
|
||||||
|
|
||||||
5. The `content` column stores the text content of the comment and is required (`nullable=False`).
|
|
||||||
|
|
||||||
|
|
||||||
|
- `id`: An auto-incrementing primary key column of type `Integer`.
|
||||||
|
- `post_id`: A foreign key column of type `Integer` that references the `id` column of the `posts` table.
|
||||||
|
- `author_id`: A foreign key column of type `Integer` that references the `id` column of the `users` table.
|
||||||
|
- `content`: A `Text` column that stores the comment content.
|
||||||
|
- `created_at`: A `String` column that stores the creation timestamp of the comment.
|
||||||
|
- `updated_at`: An optional `String` column that stores the last update timestamp of the comment.
|
||||||
|
|
||||||
|
- `post`: A relationship with the `Post` model, where each comment belongs to a post.
|
||||||
|
- `author`: A relationship with the `User` model, where each comment is written by a user.
|
||||||
|
|
||||||
|
|
||||||
|
Note: This implementation assumes that you have already defined the `Post` and `User` models in separate files, and that they have the necessary relationships defined to work with the `Comment` model.
|
@ -1,7 +1,10 @@
|
|||||||
Here's the `posts.py` file for the `app/api/v1/models/` directory of the `blog_app_igblf` FastAPI backend, defining a SQLAlchemy model for posts:
|
Here's the `posts.py` file with the SQLAlchemy model for posts:
|
||||||
|
|
||||||
|
|
||||||
from sqlalchemy import Column, ForeignKey, Integer, String, Text
|
from sqlalchemy import Column, ForeignKey, Integer, String, Text
|
||||||
from sqlalchemy.orm import relationship
|
from sqlalchemy.orm import relationship
|
||||||
|
from sqlalchemy.sql.sqltypes import TIMESTAMP
|
||||||
|
from sqlalchemy.sql import func
|
||||||
|
|
||||||
from app.db import Base
|
from app.db import Base
|
||||||
|
|
||||||
@ -9,20 +12,23 @@ class Post(Base):
|
|||||||
__tablename__ = "posts"
|
__tablename__ = "posts"
|
||||||
|
|
||||||
id = Column(Integer, primary_key=True, index=True)
|
id = Column(Integer, primary_key=True, index=True)
|
||||||
title = Column(String, index=True)
|
title = Column(String, nullable=False)
|
||||||
content = Column(Text)
|
content = Column(Text, nullable=False)
|
||||||
user_id = Column(Integer, ForeignKey("users.id"))
|
created_at = Column(TIMESTAMP, server_default=func.now())
|
||||||
|
updated_at = Column(TIMESTAMP, server_default=func.now(), onupdate=func.now())
|
||||||
|
user_id = Column(Integer, ForeignKey("users.id"), nullable=False)
|
||||||
|
|
||||||
author = relationship("User", back_populates="posts")
|
user = relationship("User", back_populates="posts")
|
||||||
|
|
||||||
This file defines a `Post` model that inherits from the `Base` class (assumed to be defined in `app.db`). The `Post` model has the following columns:
|
def __repr__(self):
|
||||||
|
return f"Post(id={self.id}, title='{self.title}', content='{self.content[:20]}...')"
|
||||||
|
|
||||||
|
Explanation:
|
||||||
|
|
||||||
The `author` attribute is a relationship with the `User` model (assumed to be defined elsewhere), using the `back_populates` parameter to create a bidirectional relationship. This means that each `Post` instance will have an `author` attribute that references the associated `User` instance, and each `User` instance will have a `posts` attribute that contains a list of associated `Post` instances.
|
5. We define the columns for the `Post` model:
|
||||||
|
- `id`: Integer primary key and index column.
|
||||||
Note that this code assumes the following:
|
- `title`: String column that cannot be null.
|
||||||
|
- `content`: Text column that cannot be null.
|
||||||
2. The `User` model is defined elsewhere (e.g., `app/api/v1/models/users.py`).
|
- `created_at`: TIMESTAMP column with a default value of the current server time.
|
||||||
3. The necessary imports for SQLAlchemy are available (e.g., `from sqlalchemy import ...`).
|
- `updated_at`: TIMESTAMP column with a default value of the current server time and updated on each update.
|
||||||
|
- `user_id`: Integer column that is a foreign key referencing the `id` column of the `users` table.
|
||||||
Make sure to import this model in the appropriate places (e.g., `app/main.py`) and create the necessary database tables using SQLAlchemy's database migration tools or by running the appropriate commands.
|
|
@ -1,7 +1,5 @@
|
|||||||
Here's the `tags.py` file with a SQLAlchemy model for tags, placed in the `app/api/v1/models/` directory:
|
Here's the `tags.py` file for the `app/api/v1/models/` directory of the `blog_app` FastAPI backend, defining a SQLAlchemy model for tags:
|
||||||
|
|
||||||
|
|
||||||
from typing import Optional
|
|
||||||
from sqlalchemy import Column, Integer, String
|
from sqlalchemy import Column, Integer, String
|
||||||
from app.db.base_class import Base
|
from app.db.base_class import Base
|
||||||
|
|
||||||
@ -10,20 +8,19 @@ class Tag(Base):
|
|||||||
|
|
||||||
id = Column(Integer, primary_key=True, index=True)
|
id = Column(Integer, primary_key=True, index=True)
|
||||||
name = Column(String, nullable=False, unique=True, index=True)
|
name = Column(String, nullable=False, unique=True, index=True)
|
||||||
description = Column(String, nullable=True)
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"Tag(id={self.id}, name='{self.name}', description='{self.description}')"
|
return f"Tag(id={self.id}, name='{self.name}')"
|
||||||
|
|
||||||
Explanation:
|
Explanation:
|
||||||
|
|
||||||
1. We import the necessary modules: `typing` for type hints, `sqlalchemy` for defining the database model, and `app.db.base_class` for the base class that inherits from `Base` (assuming you have a `base_class.py` file in the `app/db/` directory).
|
2. `from app.db.base_class import Base`: We import the `Base` class from the `base_class.py` file, which is typically a base class that inherits from SQLAlchemy's `declarative_base()`.
|
||||||
|
3. `class Tag(Base):`: We define a `Tag` class that inherits from the `Base` class.
|
||||||
|
4. `__tablename__ = "tags"`: We set the `__tablename__` attribute to specify the name of the database table for this model.
|
||||||
|
5. `id = Column(Integer, primary_key=True, index=True)`: We define an `id` column of type `Integer`, which is the primary key and indexed for faster lookups.
|
||||||
|
6. `name = Column(String, nullable=False, unique=True, index=True)`: We define a `name` column of type `String`, which cannot be null, must be unique, and is indexed for faster lookups.
|
||||||
|
7. `def __repr__(self):`: We define a `__repr__` method to provide a string representation of the `Tag` object, which is useful for debugging and logging purposes.
|
||||||
|
|
||||||
|
This model defines a simple `Tag` table with two columns: `id` (primary key) and `name` (unique string). The `__repr__` method allows you to print a readable representation of a `Tag` instance.
|
||||||
|
|
||||||
|
Make sure to import this model in your application and create the necessary database tables using SQLAlchemy's `create_all()` method or an Alembic migration script.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Note: This code assumes that you have already set up the necessary database connection and configured SQLAlchemy in your FastAPI application. If not, you'll need to add the required configuration and import statements accordingly.
|
|
@ -1,8 +1,7 @@
|
|||||||
Sure, here's the `user.py` file for the `app/api/v1/models/` directory of the `blog_app` FastAPI backend project using SQLAlchemy with SQLite:
|
from sqlalchemy import Column, Integer, String, DateTime
|
||||||
|
from sqlalchemy.orm import relationship
|
||||||
|
|
||||||
from sqlalchemy import Column, Integer, String, Boolean
|
|
||||||
from app.db import Base
|
from app.db import Base
|
||||||
|
import datetime
|
||||||
|
|
||||||
class User(Base):
|
class User(Base):
|
||||||
__tablename__ = "users"
|
__tablename__ = "users"
|
||||||
@ -10,22 +9,25 @@ class User(Base):
|
|||||||
id = Column(Integer, primary_key=True, index=True)
|
id = Column(Integer, primary_key=True, index=True)
|
||||||
username = Column(String, unique=True, index=True)
|
username = Column(String, unique=True, index=True)
|
||||||
email = Column(String, unique=True, index=True)
|
email = Column(String, unique=True, index=True)
|
||||||
hashed_password = Column(String)
|
password = Column(String)
|
||||||
is_active = Column(Boolean, default=True)
|
created_at = Column(DateTime, default=datetime.datetime.utcnow)
|
||||||
is_superuser = Column(Boolean, default=False)
|
updated_at = Column(DateTime, default=datetime.datetime.utcnow)
|
||||||
|
|
||||||
|
posts = relationship("Post", back_populates="author")
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"User(id={self.id}, username='{self.username}', email='{self.email}', is_active={self.is_active}, is_superuser={self.is_superuser})"
|
return f"User(id={self.id}, username='{self.username}', email='{self.email}')"
|
||||||
|
|
||||||
Explanation:
|
Explanation:
|
||||||
|
|
||||||
|
3. We define the table name using `__tablename__ = "users"`.
|
||||||
|
4. We define the columns for the `User` model:
|
||||||
|
- `id`: Integer primary key and index
|
||||||
|
- `username`: String, unique, and indexed
|
||||||
|
- `email`: String, unique, and indexed
|
||||||
|
- `password`: String
|
||||||
|
- `created_at`: DateTime, default set to the current UTC time
|
||||||
|
- `updated_at`: DateTime, default set to the current UTC time
|
||||||
|
5. We define a relationship `posts` that relates the `User` model to the `Post` model (which you'll need to define separately). This relationship is set up using `back_populates` to allow bidirectional access between `User` and `Post` instances.
|
||||||
|
|
||||||
|
Note: This code assumes that you have already defined a `Base` class in `app/db.py` and that you will define a `Post` model separately. Make sure to import the necessary modules and create the database tables using SQLAlchemy's `create_all` method.
|
||||||
|
|
||||||
4. We define the following columns for the `User` model:
|
|
||||||
- `id`: an integer primary key with an index
|
|
||||||
- `username`: a string column that is unique and indexed
|
|
||||||
- `email`: a string column that is unique and indexed
|
|
||||||
- `hashed_password`: a string column to store the hashed password
|
|
||||||
- `is_active`: a boolean column to indicate if the user is active or not (default is `True`)
|
|
||||||
- `is_superuser`: a boolean column to indicate if the user is a superuser or not (default is `False`)
|
|
@ -1,9 +1,10 @@
|
|||||||
Here's the `comments.py` file with CRUD endpoints for comments:
|
Here's an example of the `comments.py` file with CRUD endpoints for comments using FastAPI and SQLAlchemy:
|
||||||
|
|
||||||
from typing import List
|
from typing import List
|
||||||
from fastapi import APIRouter, Depends, HTTPException
|
from fastapi import APIRouter, Depends, HTTPException
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
from app.db.database import get_db
|
|
||||||
|
from app.db import get_db
|
||||||
from app.models import Comment
|
from app.models import Comment
|
||||||
from app.schemas import CommentCreate, CommentResponse
|
from app.schemas import CommentCreate, CommentResponse
|
||||||
|
|
||||||
@ -11,7 +12,8 @@ router = APIRouter(
|
|||||||
prefix="/comments",
|
prefix="/comments",
|
||||||
tags=["Comments"],
|
tags=["Comments"],
|
||||||
|
|
||||||
@router.post("/", response_model=CommentResponse)
|
|
||||||
|
@router.post("/", response_model=CommentResponse, status_code=201)
|
||||||
def create_comment(comment: CommentCreate, db: Session = Depends(get_db)):
|
def create_comment(comment: CommentCreate, db: Session = Depends(get_db)):
|
||||||
db_comment = Comment(**comment.dict())
|
db_comment = Comment(**comment.dict())
|
||||||
db.add(db_comment)
|
db.add(db_comment)
|
||||||
@ -19,11 +21,13 @@ def create_comment(comment: CommentCreate, db: Session = Depends(get_db)):
|
|||||||
db.refresh(db_comment)
|
db.refresh(db_comment)
|
||||||
return db_comment
|
return db_comment
|
||||||
|
|
||||||
|
|
||||||
@router.get("/", response_model=List[CommentResponse])
|
@router.get("/", response_model=List[CommentResponse])
|
||||||
def get_comments(db: Session = Depends(get_db)):
|
def get_comments(db: Session = Depends(get_db)):
|
||||||
comments = db.query(Comment).all()
|
comments = db.query(Comment).all()
|
||||||
return comments
|
return comments
|
||||||
|
|
||||||
|
|
||||||
@router.get("/{comment_id}", response_model=CommentResponse)
|
@router.get("/{comment_id}", response_model=CommentResponse)
|
||||||
def get_comment(comment_id: int, db: Session = Depends(get_db)):
|
def get_comment(comment_id: int, db: Session = Depends(get_db)):
|
||||||
comment = db.query(Comment).filter(Comment.id == comment_id).first()
|
comment = db.query(Comment).filter(Comment.id == comment_id).first()
|
||||||
@ -31,25 +35,26 @@ def get_comment(comment_id: int, db: Session = Depends(get_db)):
|
|||||||
raise HTTPException(status_code=404, detail="Comment not found")
|
raise HTTPException(status_code=404, detail="Comment not found")
|
||||||
return comment
|
return comment
|
||||||
|
|
||||||
|
|
||||||
@router.put("/{comment_id}", response_model=CommentResponse)
|
@router.put("/{comment_id}", response_model=CommentResponse)
|
||||||
def update_comment(comment_id: int, comment: CommentCreate, db: Session = Depends(get_db)):
|
def update_comment(comment_id: int, comment: CommentCreate, db: Session = Depends(get_db)):
|
||||||
db_comment = db.query(Comment).filter(Comment.id == comment_id).first()
|
db_comment = db.query(Comment).filter(Comment.id == comment_id).first()
|
||||||
if not db_comment:
|
if not db_comment:
|
||||||
raise HTTPException(status_code=404, detail="Comment not found")
|
raise HTTPException(status_code=404, detail="Comment not found")
|
||||||
update_data = comment.dict(exclude_unset=True)
|
for field, value in comment.dict().items():
|
||||||
for key, value in update_data.items():
|
setattr(db_comment, field, value)
|
||||||
setattr(db_comment, key, value)
|
|
||||||
db.commit()
|
db.commit()
|
||||||
db.refresh(db_comment)
|
db.refresh(db_comment)
|
||||||
return db_comment
|
return db_comment
|
||||||
|
|
||||||
@router.delete("/{comment_id}", response_model=CommentResponse)
|
|
||||||
|
@router.delete("/{comment_id}", status_code=204)
|
||||||
def delete_comment(comment_id: int, db: Session = Depends(get_db)):
|
def delete_comment(comment_id: int, db: Session = Depends(get_db)):
|
||||||
comment = db.query(Comment).filter(Comment.id == comment_id).first()
|
comment = db.query(Comment).filter(Comment.id == comment_id).first()
|
||||||
if not comment:
|
if not comment:
|
||||||
raise HTTPException(status_code=404, detail="Comment not found")
|
raise HTTPException(status_code=404, detail="Comment not found")
|
||||||
db.delete(comment)
|
db.delete(comment)
|
||||||
db.commit()
|
db.commit()
|
||||||
return comment
|
return {"message": "Comment deleted successfully"}
|
||||||
|
|
||||||
This file defines the following endpoints:
|
This file defines the following endpoints:
|
@ -1,59 +1,57 @@
|
|||||||
Here's the `posts.py` file with CRUD endpoints for posts:
|
Here's the `posts.py` file with CRUD endpoints for posts:
|
||||||
|
|
||||||
from typing import List
|
from typing import List
|
||||||
from fastapi import APIRouter, Depends, HTTPException, status
|
from fastapi import APIRouter, Depends, HTTPException
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
|
from app.db import get_db
|
||||||
from app.models import Post
|
from app.models import Post
|
||||||
from app.schemas import PostCreate, PostResponse
|
from app.schemas import PostCreate, PostResponse
|
||||||
from app.database import get_db
|
|
||||||
|
|
||||||
router = APIRouter(
|
router = APIRouter()
|
||||||
prefix="/posts",
|
|
||||||
tags=["Posts"],
|
|
||||||
|
|
||||||
@router.post("/", response_model=PostResponse, status_code=status.HTTP_201_CREATED)
|
@router.get("/posts", response_model=List[PostResponse])
|
||||||
def create_post(post: PostCreate, db: Session = Depends(get_db)):
|
def get_posts(db: Session = Depends(get_db)):
|
||||||
new_post = Post(**post.dict())
|
|
||||||
db.add(new_post)
|
|
||||||
db.commit()
|
|
||||||
db.refresh(new_post)
|
|
||||||
return new_post
|
|
||||||
|
|
||||||
@router.get("/", response_model=List[PostResponse])
|
|
||||||
def get_all_posts(db: Session = Depends(get_db)):
|
|
||||||
posts = db.query(Post).all()
|
posts = db.query(Post).all()
|
||||||
return posts
|
return posts
|
||||||
|
|
||||||
@router.get("/{post_id}", response_model=PostResponse)
|
@router.post("/posts", response_model=PostResponse)
|
||||||
def get_post(post_id: int, db: Session = Depends(get_db)):
|
def create_post(post: PostCreate, db: Session = Depends(get_db)):
|
||||||
post = db.query(Post).filter(Post.id == post_id).first()
|
db_post = Post(**post.dict())
|
||||||
if not post:
|
db.add(db_post)
|
||||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Post not found")
|
|
||||||
return post
|
|
||||||
|
|
||||||
@router.put("/{post_id}", response_model=PostResponse)
|
|
||||||
def update_post(post_id: int, post: PostCreate, db: Session = Depends(get_db)):
|
|
||||||
db_post = db.query(Post).filter(Post.id == post_id).first()
|
|
||||||
if not db_post:
|
|
||||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Post not found")
|
|
||||||
for key, value in post.dict().items():
|
|
||||||
setattr(db_post, key, value)
|
|
||||||
db.commit()
|
db.commit()
|
||||||
db.refresh(db_post)
|
db.refresh(db_post)
|
||||||
return db_post
|
return db_post
|
||||||
|
|
||||||
@router.delete("/{post_id}", status_code=status.HTTP_204_NO_CONTENT)
|
@router.get("/posts/{post_id}", response_model=PostResponse)
|
||||||
|
def get_post(post_id: int, db: Session = Depends(get_db)):
|
||||||
|
post = db.query(Post).filter(Post.id == post_id).first()
|
||||||
|
if not post:
|
||||||
|
raise HTTPException(status_code=404, detail="Post not found")
|
||||||
|
return post
|
||||||
|
|
||||||
|
@router.put("/posts/{post_id}", response_model=PostResponse)
|
||||||
|
def update_post(post_id: int, post: PostCreate, db: Session = Depends(get_db)):
|
||||||
|
db_post = db.query(Post).filter(Post.id == post_id).first()
|
||||||
|
if not db_post:
|
||||||
|
raise HTTPException(status_code=404, detail="Post not found")
|
||||||
|
for field, value in post.dict().items():
|
||||||
|
setattr(db_post, field, value)
|
||||||
|
db.commit()
|
||||||
|
db.refresh(db_post)
|
||||||
|
return db_post
|
||||||
|
|
||||||
|
@router.delete("/posts/{post_id}", response_model=PostResponse)
|
||||||
def delete_post(post_id: int, db: Session = Depends(get_db)):
|
def delete_post(post_id: int, db: Session = Depends(get_db)):
|
||||||
post = db.query(Post).filter(Post.id == post_id).first()
|
post = db.query(Post).filter(Post.id == post_id).first()
|
||||||
if not post:
|
if not post:
|
||||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Post not found")
|
raise HTTPException(status_code=404, detail="Post not found")
|
||||||
db.delete(post)
|
db.delete(post)
|
||||||
db.commit()
|
db.commit()
|
||||||
return
|
return post
|
||||||
|
|
||||||
This file defines the following endpoints:
|
This file defines the following endpoints:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Note: Make sure you have the `Post` model, `PostCreate` and `PostResponse` schemas, and the `get_db` dependency defined in your project.
|
Note: Make sure to import the necessary models and schemas in the `app/models.py` and `app/schemas.py` files, respectively.
|
@ -3,12 +3,12 @@ from fastapi import APIRouter, Depends, HTTPException
|
|||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
from app.db.session import get_db
|
from app.db.session import get_db
|
||||||
from app.models import Tag
|
from app.models.tag import Tag
|
||||||
from app.schemas.tag import TagCreate, TagUpdate, TagOut
|
from app.schemas.tag import TagCreate, TagUpdate, TagResponse
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
@router.post("/tags", response_model=TagOut, status_code=201)
|
@router.post("/tags", response_model=TagResponse, status_code=201)
|
||||||
def create_tag(tag: TagCreate, db: Session = Depends(get_db)):
|
def create_tag(tag: TagCreate, db: Session = Depends(get_db)):
|
||||||
db_tag = Tag(**tag.dict())
|
db_tag = Tag(**tag.dict())
|
||||||
db.add(db_tag)
|
db.add(db_tag)
|
||||||
@ -16,19 +16,19 @@ def create_tag(tag: TagCreate, db: Session = Depends(get_db)):
|
|||||||
db.refresh(db_tag)
|
db.refresh(db_tag)
|
||||||
return db_tag
|
return db_tag
|
||||||
|
|
||||||
@router.get("/tags", response_model=List[TagOut])
|
@router.get("/tags", response_model=List[TagResponse])
|
||||||
def read_tags(db: Session = Depends(get_db)):
|
def get_all_tags(db: Session = Depends(get_db)):
|
||||||
tags = db.query(Tag).all()
|
tags = db.query(Tag).all()
|
||||||
return tags
|
return tags
|
||||||
|
|
||||||
@router.get("/tags/{tag_id}", response_model=TagOut)
|
@router.get("/tags/{tag_id}", response_model=TagResponse)
|
||||||
def read_tag(tag_id: int, db: Session = Depends(get_db)):
|
def get_tag(tag_id: int, db: Session = Depends(get_db)):
|
||||||
db_tag = db.query(Tag).filter(Tag.id == tag_id).first()
|
db_tag = db.query(Tag).filter(Tag.id == tag_id).first()
|
||||||
if not db_tag:
|
if not db_tag:
|
||||||
raise HTTPException(status_code=404, detail="Tag not found")
|
raise HTTPException(status_code=404, detail="Tag not found")
|
||||||
return db_tag
|
return db_tag
|
||||||
|
|
||||||
@router.put("/tags/{tag_id}", response_model=TagOut)
|
@router.put("/tags/{tag_id}", response_model=TagResponse)
|
||||||
def update_tag(tag_id: int, tag: TagUpdate, db: Session = Depends(get_db)):
|
def update_tag(tag_id: int, tag: TagUpdate, db: Session = Depends(get_db)):
|
||||||
db_tag = db.query(Tag).filter(Tag.id == tag_id).first()
|
db_tag = db.query(Tag).filter(Tag.id == tag_id).first()
|
||||||
if not db_tag:
|
if not db_tag:
|
||||||
@ -36,7 +36,6 @@ def update_tag(tag_id: int, tag: TagUpdate, db: Session = Depends(get_db)):
|
|||||||
update_data = tag.dict(exclude_unset=True)
|
update_data = tag.dict(exclude_unset=True)
|
||||||
for key, value in update_data.items():
|
for key, value in update_data.items():
|
||||||
setattr(db_tag, key, value)
|
setattr(db_tag, key, value)
|
||||||
db.add(db_tag)
|
|
||||||
db.commit()
|
db.commit()
|
||||||
db.refresh(db_tag)
|
db.refresh(db_tag)
|
||||||
return db_tag
|
return db_tag
|
||||||
@ -50,11 +49,8 @@ def delete_tag(tag_id: int, db: Session = Depends(get_db)):
|
|||||||
db.commit()
|
db.commit()
|
||||||
return None
|
return None
|
||||||
|
|
||||||
This code defines a set of CRUD endpoints for managing tags in the `blog_app_igblf` FastAPI application. Here's a breakdown of the different endpoints:
|
This file defines the following endpoints:
|
||||||
|
|
||||||
1. `POST /tags`: Creates a new tag. It expects a `TagCreate` Pydantic model in the request body and returns the created `TagOut` model with a status code of 201 (Created).
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Note: This code assumes that you have already defined the `Tag` model and the `TagCreate`, `TagUpdate`, and `TagResponse` Pydantic schemas in their respective files. Additionally, you need to include this `tags.py` file in your FastAPI application by adding it to the router.
|
||||||
5. `DELETE /tags/{tag_id}`: Deletes a tag by its ID. If the tag is found, it is deleted from the database and returns a 204 (No Content) status code. If the tag is not found, it raises an HTTP 404 exception.
|
|
@ -1,61 +1,53 @@
|
|||||||
from typing import List
|
from typing import List
|
||||||
from fastapi import APIRouter, Depends, HTTPException
|
from fastapi import APIRouter, Depends, HTTPException
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
from app.db import get_db
|
||||||
from app.core.security import get_current_user
|
from app.models.user import User as UserModel
|
||||||
from app.db.session import get_db
|
from app.schemas.user import User, UserCreate, UserUpdate
|
||||||
from app.models import User
|
|
||||||
from app.schemas.user import UserCreate, UserRead, UserUpdate
|
|
||||||
|
|
||||||
router = APIRouter(
|
router = APIRouter(
|
||||||
prefix="/users",
|
prefix="/users",
|
||||||
tags=["users"],
|
tags=["Users"],
|
||||||
|
|
||||||
@router.post("/", response_model=UserRead)
|
@router.post("/", response_model=User)
|
||||||
def create_user(user: UserCreate, db: Session = Depends(get_db)):
|
def create_user(user: UserCreate, db: Session = Depends(get_db)):
|
||||||
db_user = User(**user.dict())
|
db_user = UserModel(**user.dict())
|
||||||
db.add(db_user)
|
db.add(db_user)
|
||||||
db.commit()
|
db.commit()
|
||||||
db.refresh(db_user)
|
db.refresh(db_user)
|
||||||
return db_user
|
return db_user
|
||||||
|
|
||||||
@router.get("/", response_model=List[UserRead])
|
@router.get("/", response_model=List[User])
|
||||||
def read_users(db: Session = Depends(get_db), current_user: User = Depends(get_current_user)):
|
def read_users(db: Session = Depends(get_db)):
|
||||||
users = db.query(User).all()
|
users = db.query(UserModel).all()
|
||||||
return users
|
return users
|
||||||
|
|
||||||
@router.get("/{user_id}", response_model=UserRead)
|
@router.get("/{user_id}", response_model=User)
|
||||||
def read_user(user_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user)):
|
def read_user(user_id: int, db: Session = Depends(get_db)):
|
||||||
db_user = db.query(User).filter(User.id == user_id).first()
|
db_user = db.query(UserModel).filter(UserModel.id == user_id).first()
|
||||||
if not db_user:
|
if not db_user:
|
||||||
raise HTTPException(status_code=404, detail="User not found")
|
raise HTTPException(status_code=404, detail="User not found")
|
||||||
return db_user
|
return db_user
|
||||||
|
|
||||||
@router.put("/{user_id}", response_model=UserRead)
|
@router.put("/{user_id}", response_model=User)
|
||||||
def update_user(user_id: int, user: UserUpdate, db: Session = Depends(get_db), current_user: User = Depends(get_current_user)):
|
def update_user(user_id: int, user: UserUpdate, db: Session = Depends(get_db)):
|
||||||
db_user = db.query(User).filter(User.id == user_id).first()
|
db_user = db.query(UserModel).filter(UserModel.id == user_id).first()
|
||||||
if not db_user:
|
if not db_user:
|
||||||
raise HTTPException(status_code=404, detail="User not found")
|
raise HTTPException(status_code=404, detail="User not found")
|
||||||
user_data = user.dict(exclude_unset=True)
|
update_data = user.dict(exclude_unset=True)
|
||||||
for key, value in user_data.items():
|
for key, value in update_data.items():
|
||||||
setattr(db_user, key, value)
|
setattr(db_user, key, value)
|
||||||
db.add(db_user)
|
|
||||||
db.commit()
|
db.commit()
|
||||||
db.refresh(db_user)
|
db.refresh(db_user)
|
||||||
return db_user
|
return db_user
|
||||||
|
|
||||||
@router.delete("/{user_id}", response_model=UserRead)
|
@router.delete("/{user_id}")
|
||||||
def delete_user(user_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user)):
|
def delete_user(user_id: int, db: Session = Depends(get_db)):
|
||||||
db_user = db.query(User).filter(User.id == user_id).first()
|
db_user = db.query(UserModel).filter(UserModel.id == user_id).first()
|
||||||
if not db_user:
|
if not db_user:
|
||||||
raise HTTPException(status_code=404, detail="User not found")
|
raise HTTPException(status_code=404, detail="User not found")
|
||||||
db.delete(db_user)
|
db.delete(db_user)
|
||||||
db.commit()
|
db.commit()
|
||||||
return db_user
|
return {"message": "User deleted successfully"}
|
||||||
|
|
||||||
This file defines the following endpoints:
|
This file defines the following endpoints:
|
||||||
|
|
||||||
|
|
||||||
The endpoints use SQLAlchemy models and Pydantic schemas for data validation and serialization. The `get_current_user` dependency is used to ensure that only authenticated users can access certain endpoints (e.g., read all users, read a single user, update a user, and delete a user).
|
|
||||||
|
|
||||||
Note that you'll need to define the `User`, `UserCreate`, `UserRead`, and `UserUpdate` models and schemas in separate files (e.g., `app/models.py` and `app/schemas/user.py`). Additionally, you'll need to implement the `get_current_user` function in `app/core/security.py` to handle user authentication and authorization.
|
|
@ -1,14 +1,12 @@
|
|||||||
Sure, here's the `comments.py` file for the `app/api/v1/schemas/` directory in the `blog_app_igblf` FastAPI backend:
|
Here's the `comments.py` file for the `app/api/v1/schemas/` directory in the `blog_app_igblf` FastAPI backend project:
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel
|
||||||
|
|
||||||
from app.db.base_class import Base
|
|
||||||
|
|
||||||
class CommentBase(BaseModel):
|
class CommentBase(BaseModel):
|
||||||
content: str = Field(..., min_length=1, max_length=1000)
|
content: str
|
||||||
|
|
||||||
class CommentCreate(CommentBase):
|
class CommentCreate(CommentBase):
|
||||||
pass
|
pass
|
||||||
@ -18,9 +16,9 @@ class CommentUpdate(CommentBase):
|
|||||||
|
|
||||||
class CommentInDBBase(CommentBase):
|
class CommentInDBBase(CommentBase):
|
||||||
id: int
|
id: int
|
||||||
|
post_id: int
|
||||||
created_at: datetime
|
created_at: datetime
|
||||||
updated_at: Optional[datetime] = None
|
updated_at: Optional[datetime] = None
|
||||||
post_id: int
|
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
orm_mode = True
|
orm_mode = True
|
||||||
@ -33,11 +31,4 @@ class CommentInDB(CommentInDBBase):
|
|||||||
|
|
||||||
This file defines the following Pydantic models for comments:
|
This file defines the following Pydantic models for comments:
|
||||||
|
|
||||||
|
4. `CommentInDBBase`: A base model that includes fields for the comment ID (`id`), the associated post ID (`post_id`), the creation timestamp (`created_at`), and an optional update timestamp (`updated_at`). This model inherits from `CommentBase` and includes the `orm_mode` configuration to allow reading data from an SQLAlchemy model.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Note: You may need to adjust the import statements and the `Base` class import based on the actual structure of your `blog_app_igblf` project.
|
|
@ -1,31 +1,39 @@
|
|||||||
Here's the `posts.py` file with Pydantic schemas for posts, which can be placed in the `app/api/v1/schemas/` directory:
|
Here's the `posts.py` file with Pydantic schemas for posts, following the FastAPI project structure with SQLite and SQLAlchemy:
|
||||||
|
|
||||||
|
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from pydantic import BaseModel
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
class PostCreate(BaseModel):
|
class PostBase(BaseModel):
|
||||||
title: str
|
title: str
|
||||||
content: str
|
content: str
|
||||||
|
|
||||||
class PostRead(BaseModel):
|
class PostCreate(PostBase):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class PostUpdate(PostBase):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class PostInDBBase(PostBase):
|
||||||
id: int
|
id: int
|
||||||
title: str
|
|
||||||
content: str
|
|
||||||
created_at: datetime
|
created_at: datetime
|
||||||
updated_at: Optional[datetime] = None
|
updated_at: Optional[datetime] = None
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
orm_mode = True
|
orm_mode = True
|
||||||
|
|
||||||
class PostUpdate(BaseModel):
|
class Post(PostInDBBase):
|
||||||
title: Optional[str] = None
|
pass
|
||||||
content: Optional[str] = None
|
|
||||||
|
class PostInDB(PostInDBBase):
|
||||||
|
pass
|
||||||
|
|
||||||
Explanation:
|
Explanation:
|
||||||
|
|
||||||
1. `PostCreate` is a Pydantic model that defines the required fields (`title` and `content`) for creating a new post.
|
1. We import the necessary modules: `typing` for type hints, `datetime` for dealing with date and time objects, and `pydantic` for defining data models.
|
||||||
3. `PostUpdate` is a Pydantic model that defines the optional fields (`title` and `content`) for updating an existing post.
|
|
||||||
|
|
||||||
|
|
||||||
Note: Make sure to import the necessary dependencies (`typing`, `pydantic`, and `datetime`) at the top of the file.
|
|
||||||
|
|
||||||
|
5. `PostInDBBase` inherits from `PostBase` and includes additional fields: `id`, `created_at`, and `updated_at`. It also sets the `orm_mode` configuration to `True` for compatibility with SQLAlchemy models.
|
@ -1,3 +1,5 @@
|
|||||||
|
Here's the `tags.py` file with Pydantic schemas for tags, which can be placed in the `app/api/v1/schemas/` directory:
|
||||||
|
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
@ -7,21 +9,23 @@ class TagBase(BaseModel):
|
|||||||
class TagCreate(TagBase):
|
class TagCreate(TagBase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class TagUpdate(BaseModel):
|
class TagUpdate(TagBase):
|
||||||
name: Optional[str] = None
|
pass
|
||||||
|
|
||||||
class TagResponse(TagBase):
|
class TagInDBBase(TagBase):
|
||||||
id: int
|
id: int
|
||||||
|
name: str
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
orm_mode = True
|
orm_mode = True
|
||||||
|
|
||||||
This file defines the following Pydantic schemas for tags:
|
class Tag(TagInDBBase):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class TagInDB(TagInDBBase):
|
||||||
|
pass
|
||||||
|
|
||||||
|
Explanation:
|
||||||
|
|
||||||
|
1. We import the necessary dependencies: `typing` for type hints and `pydantic` for defining data models.
|
||||||
|
5. `TagInDBBase` inherits from `TagBase` and includes an `id` field. It also sets `orm_mode = True` in the `Config` class, which allows Pydantic to work with SQLAlchemy models.
|
||||||
The `orm_mode = True` configuration in the `TagResponse` schema tells Pydantic to read data from an ORM model (SQLAlchemy in this case) or a dict-like object, rather than just a dict.
|
|
||||||
|
|
||||||
Note: This file assumes that you have the necessary imports and dependencies set up in your FastAPI project structure, including Pydantic and SQLAlchemy (if you're using it for database operations).
|
|
@ -1,4 +1,4 @@
|
|||||||
Here's the `user.py` file that defines Pydantic schemas for the user model in the `app/api/v1/schemas/` directory of the `blog_app_igblf` FastAPI backend:
|
Here's the `user.py` file with Pydantic schemas for user in the `app/api/v1/schemas/` directory:
|
||||||
|
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from pydantic import BaseModel, EmailStr
|
from pydantic import BaseModel, EmailStr
|
||||||
@ -6,7 +6,7 @@ from pydantic import BaseModel, EmailStr
|
|||||||
class UserBase(BaseModel):
|
class UserBase(BaseModel):
|
||||||
email: EmailStr
|
email: EmailStr
|
||||||
is_active: Optional[bool] = True
|
is_active: Optional[bool] = True
|
||||||
is_superuser: Optional[bool] = False
|
is_superuser: bool = False
|
||||||
full_name: Optional[str] = None
|
full_name: Optional[str] = None
|
||||||
|
|
||||||
class UserCreate(UserBase):
|
class UserCreate(UserBase):
|
||||||
@ -15,17 +15,27 @@ class UserCreate(UserBase):
|
|||||||
class UserUpdate(UserBase):
|
class UserUpdate(UserBase):
|
||||||
password: Optional[str] = None
|
password: Optional[str] = None
|
||||||
|
|
||||||
class User(UserBase):
|
class UserInDBBase(UserBase):
|
||||||
id: int
|
id: Optional[int] = None
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
orm_mode = True
|
orm_mode = True
|
||||||
|
|
||||||
This file defines the following Pydantic schemas:
|
class User(UserInDBBase):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class UserInDB(UserInDBBase):
|
||||||
|
hashed_password: str
|
||||||
|
|
||||||
|
Explanation:
|
||||||
|
|
||||||
|
1. We import the necessary modules: `typing` for type hints, `pydantic` for defining data models, and `EmailStr` from `pydantic` for email validation.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Note: Make sure to import the necessary dependencies, such as `pydantic` and `typing`, at the top of the file.
|
|
||||||
|
|
||||||
|
Note: This file assumes that you have already set up the necessary dependencies and project structure for your FastAPI application. Make sure to import and use these schemas in the appropriate parts of your application, such as the API routes and database models.
|
@ -1,5 +1 @@
|
|||||||
fastapi
|
Here's the `requirements.txt` file for the 'blog_app' FastAPI backend:
|
||||||
uvicorn
|
|
||||||
sqlalchemy
|
|
||||||
pydantic
|
|
||||||
loguru
|
|
Loading…
x
Reference in New Issue
Block a user