mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-22 20:12:00 -06:00
Fixes #8715: eliminates duplicates when used in many-to-many field constraints
When using permissions that use tags, a user may receive multiple permissions of the same type if multiple tags are assigned to the device. This causes the RestrictedQuerySet class to generate a query similar to this: >>> dcim.models.Device.objects.filter(Q(tags__name='tag1')|Q(tags__name='tag2')) <ConfigContextModelQuerySet [<Device: device1>, <Device: device1>]> This query returns the same object twice if both tags are assigned to it. This is due to the use of the django-taggit library. The library's documentation describes this behavior as expected and suggests using an explicit distinct() call in queries to avoid duplicates. However, the use of DISTINCT in queries has a global side effect - deduplication of responses, which may or may not be acceptable behavior (depending on further use). Since it is not known how RestrictedQuerySet will be used in the rest of the code, it was decided to dedupe using a subquery.
This commit is contained in:
parent
3436905744
commit
90257e9dee
@ -39,6 +39,12 @@ class RestrictedQuerySet(QuerySet):
|
||||
# Any permission with null constraints grants access to _all_ instances
|
||||
attrs = Q()
|
||||
break
|
||||
else:
|
||||
# for else, when no break
|
||||
# avoid duplicates when JOIN on many-to-many fields without using DISTINCT.
|
||||
# DISTINCT acts globally on the entire request, which may not be desirable.
|
||||
allowed_objects = self.model.objects.filter(attrs)
|
||||
attrs = Q(pk__in=allowed_objects)
|
||||
qs = self.filter(attrs)
|
||||
|
||||
return qs
|
||||
|
Loading…
Reference in New Issue
Block a user