Comments (3)
Example for improvement in guardian shortcuts for direct model:
if not any_perm and len(codenames): objects = queryset.filter(pk__in=Subquery(groups_obj_perms_queryset.values(fields[0]))) return objects
from django-guardian.
@ericmuijs
Yeah, there are some performance pitfalls specially in the shortcuts, You can send a PR imporving that (Supprots are very wellcome for the project #603)
from django-guardian.
Ended up writing a direct model only shortcut for another project. This may be useful for some people and maybe a PR can come out of it. Though I wasn't able to update the core library. Should result in a single query
from functools import reduce
from operator import and_, or_
from typing import List, TypeVar, Union, cast
from django.contrib.auth.models import AbstractBaseUser, AnonymousUser
from django.db.models import Exists, Model, OuterRef, Q, QuerySet
from guardian.utils import get_group_obj_perms_model, get_user_obj_perms_model
T = TypeVar("T", bound=Model)
def get_objects_for_user(
user: Union[AbstractBaseUser, AnonymousUser],
perms: List[str],
klass: QuerySet[T],
any_perm: bool = False,
) -> QuerySet[T]:
"""
Fetches a queryset of objects for which the user has specified permissions.
Acts as a replacement for Django Guardian's `get_objects_for_user`, aiming
for flexible and efficient permission checks using Django's ORM.
Args:
user: User for whom to retrieve objects.
perms: Permission strings to check.
klass: Initial queryset of model objects.
any_perm: If True, returns objects for any permissions. Else, all.
Returns:
A queryset of objects with the specified permissions for the user.
Note:
- Dynamically builds queries for user/group permissions.
- Requires `klass` as a correct model type queryset and `perms` to be
model-appropriate permission codenames.
- Custom `UserObjectPermission` and `GroupObjectPermission` models
associate permissions with model instances, enabling granular access
control.
"""
if not user.is_authenticated or not perms:
return klass.none()
user_permissions_field = get_user_obj_perms_model(
klass.model
).permission.field.related_query_name()
group_permissions_field = get_group_obj_perms_model(
klass.model
).permission.field.related_query_name()
qs = klass
permission_filters = []
for perm in perms:
perm_codename = perm.split(".")[-1]
user_perm_query = Q(
**{
f"{user_permissions_field}__permission__codename": perm_codename,
f"{user_permissions_field}__user": user,
}
)
group_perm_query = Q(
**{
f"{group_permissions_field}__permission__codename": perm_codename,
f"{group_permissions_field}__group__user": user,
}
)
permission_filters.append(
Exists(klass.filter(user_perm_query | group_perm_query, pk=OuterRef("pk")))
)
if any_perm:
combined_condition = reduce(or_, permission_filters)
else:
combined_condition = reduce(and_, permission_filters)
return cast(
QuerySet[T],
qs.annotate(has_permission=combined_condition).filter(has_permission=True),
)
from django-guardian.
Related Issues (20)
- Checking permission of tweaked direct-foreign-keys HOT 3
- How to suggest a selection at dropdown menu on the admin site HOT 2
- get_perms returns empty list while get_user_perms returns permissions HOT 2
- Support `only_with_perms_in` in `shortcuts.get_groups_with_perms`
- has_perm returns False despite perms being present HOT 1
- Get objects with no permissions assigned HOT 1
- perfetch_perms fails on empty list
- Unable to create anonymous user HOT 3
- Assiging Permissions not Designed for the Class
- Enabling Discussions on the repo HOT 1
- N+1 Query
- [Feature Request] Add support for Django 4.2 HOT 2
- capture or provide way to capture change_permission events HOT 3
- Async support for PermissionRequiredMixin
- Async support for PermissionRequiredMixin HOT 2
- Provide a shortcut function for "reassigning" user permissions. HOT 1
- Performance Issue in filter_perms_queryset_by_objects
- `prefetch_terms(queryset)` evaluates queryset twice via `values_list()`
- assign_perm doesn't work for user permission, if group permission is already there
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from django-guardian.