-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Filters in automatic crud router #41
Comments
Hey, @mick-net, I'm really glad you like it! It's currently possible to do something like this, but not simple. You could just write a subclass of endpointcreator that accepts a filter (like the id), and passes it to all the endpoint methods. You would have to explicitly pass it to the endpoint methods in this subclass, but once it's ready you can just pass this custom EndpointCreator to crud_router. You could do something like: # creating a dependency to get the user
from fastapi import Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
async def get_user_id(token: str = Depends(oauth2_scheme)):
# Here, you would decode the token, verify it, and extract the user_id
user_id = decode_token_to_user_id(token) # Implement this function based on your auth system
if not user_id:
raise HTTPException(status_code=401, detail="Invalid token or expired token.")
return user_id Overwrite all methods in EndpointCreator with the custom logic # overwrite all methods in EndpointCreator
# the only actual change is the new dependency in the endpoint function plus the filter in the crud method
class UserFilteredEndpointCreator(EndpointCreator):
def _read_item(self):
"""Override to apply user_id filter for single item read."""
@apply_model_pk(**self._primary_keys_types)
async def endpoint(
db: AsyncSession = Depends(self.session),
user_id: int = Depends(get_user_id), **pkeys
):
item = await self.crud.get(db, **pkeys, user_id=user_id)
if not item:
raise NotFoundException(detail="Item not found")
return item
return endpoint
def _read_items(self):
"""Override to apply user_id filter for reading multiple items."""
async def endpoint(
db: AsyncSession = Depends(self.session),
user_id: int = Depends(get_user_id),
offset: int = Query(0),
limit: int = Query(100),
):
return await self.crud.get_multi(db, offset=offset, limit=limit, user_id=user_id)
return endpoint
# do it for all relevant methods
... Pass this custom EndpointCreator to crud_router: app.include_router(
crud_router(
session=async_session,
model=YourModel,
crud=FastCRUD(YourModel),
create_schema=CreateYourModelSchema,
update_schema=UpdateYourModelSchema,
delete_schema=DeleteYourModelSchema,
endpoint_creator=UserFilteredEndpointCreator, # Use your subclass here
path="/yourmodel",
tags=["YourModel"],
)
) And it would work properly. I agree that this is not the best way to do it, and I think it would be a nice feature, but I'm first making sure So, unless someone works on it, I'll do it not too much in the future! |
First of all: I love FastCrud
Is your feature request related to a problem? Please describe.
Using the automatic
crud_router
functionality I'm missing the option to filter (all) routes on a specific column.For example the automatic crud router works great when using a Todo model with
However, when I add a
user_id
to the todo model I cannot find any (advanced) option to filter the automatically generated routes on a value (like the user_id of the currently logged-in user). Currently, I'm manually creating e.g. afastcrud.get
route that manually adds user_id kwarg.Describe the solution you'd like
I'm not sure what the best option would be but maybe the following crud_router arguments:
read_filter
,create_filter
,update_filter
,delete_filter
can be added.Example:
Would do something like this under the hood:
Describe alternatives you've considered
Currently manually creating each router with a filter variables. So while this is still very doable it still feels like a lot of repetitive code of you have to add this filter for all CRUD routes. For example:
Additional context
Maybe I'm missing something and this is already implemented?
I see a request for filters in the multi get, but this request is still different I think:
#15
The text was updated successfully, but these errors were encountered: