mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Call Coalesce() inside get_queryset()
This commit is contained in:
@ -1,5 +1,4 @@
|
|||||||
from django.db.models import Prefetch
|
from django.db.models import Prefetch
|
||||||
from django.db.models.functions import Coalesce
|
|
||||||
from rest_framework.routers import APIRootView
|
from rest_framework.routers import APIRootView
|
||||||
|
|
||||||
from circuits import filters
|
from circuits import filters
|
||||||
@ -25,7 +24,7 @@ class CircuitsRootView(APIRootView):
|
|||||||
|
|
||||||
class ProviderViewSet(CustomFieldModelViewSet):
|
class ProviderViewSet(CustomFieldModelViewSet):
|
||||||
queryset = Provider.objects.prefetch_related('tags').annotate(
|
queryset = Provider.objects.prefetch_related('tags').annotate(
|
||||||
circuit_count=Coalesce(get_subquery(Circuit, 'provider'), 0)
|
circuit_count=get_subquery(Circuit, 'provider')
|
||||||
)
|
)
|
||||||
serializer_class = serializers.ProviderSerializer
|
serializer_class = serializers.ProviderSerializer
|
||||||
filterset_class = filters.ProviderFilterSet
|
filterset_class = filters.ProviderFilterSet
|
||||||
@ -37,7 +36,7 @@ class ProviderViewSet(CustomFieldModelViewSet):
|
|||||||
|
|
||||||
class CircuitTypeViewSet(ModelViewSet):
|
class CircuitTypeViewSet(ModelViewSet):
|
||||||
queryset = CircuitType.objects.annotate(
|
queryset = CircuitType.objects.annotate(
|
||||||
circuit_count=Coalesce(get_subquery(Circuit, 'type'), 0)
|
circuit_count=get_subquery(Circuit, 'type')
|
||||||
)
|
)
|
||||||
serializer_class = serializers.CircuitTypeSerializer
|
serializer_class = serializers.CircuitTypeSerializer
|
||||||
filterset_class = filters.CircuitTypeFilterSet
|
filterset_class = filters.CircuitTypeFilterSet
|
||||||
|
@ -3,7 +3,6 @@ from collections import OrderedDict
|
|||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db.models import F
|
from django.db.models import F
|
||||||
from django.db.models.functions import Coalesce
|
|
||||||
from django.http import HttpResponseForbidden, HttpResponse
|
from django.http import HttpResponseForbidden, HttpResponse
|
||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
from drf_yasg import openapi
|
from drf_yasg import openapi
|
||||||
@ -120,12 +119,12 @@ class SiteViewSet(CustomFieldModelViewSet):
|
|||||||
queryset = Site.objects.prefetch_related(
|
queryset = Site.objects.prefetch_related(
|
||||||
'region', 'tenant', 'tags'
|
'region', 'tenant', 'tags'
|
||||||
).annotate(
|
).annotate(
|
||||||
device_count=Coalesce(get_subquery(Device, 'site'), 0),
|
device_count=get_subquery(Device, 'site'),
|
||||||
rack_count=Coalesce(get_subquery(Rack, 'site'), 0),
|
rack_count=get_subquery(Rack, 'site'),
|
||||||
prefix_count=Coalesce(get_subquery(Prefix, 'site'), 0),
|
prefix_count=get_subquery(Prefix, 'site'),
|
||||||
vlan_count=Coalesce(get_subquery(VLAN, 'site'), 0),
|
vlan_count=get_subquery(VLAN, 'site'),
|
||||||
circuit_count=Coalesce(get_subquery(Circuit, 'terminations__site'), 0),
|
circuit_count=get_subquery(Circuit, 'terminations__site'),
|
||||||
virtualmachine_count=Coalesce(get_subquery(VirtualMachine, 'cluster__site'), 0),
|
virtualmachine_count=get_subquery(VirtualMachine, 'cluster__site')
|
||||||
)
|
)
|
||||||
serializer_class = serializers.SiteSerializer
|
serializer_class = serializers.SiteSerializer
|
||||||
filterset_class = filters.SiteFilterSet
|
filterset_class = filters.SiteFilterSet
|
||||||
@ -153,7 +152,7 @@ class RackGroupViewSet(ModelViewSet):
|
|||||||
|
|
||||||
class RackRoleViewSet(ModelViewSet):
|
class RackRoleViewSet(ModelViewSet):
|
||||||
queryset = RackRole.objects.annotate(
|
queryset = RackRole.objects.annotate(
|
||||||
rack_count=Coalesce(get_subquery(Rack, 'role'), 0)
|
rack_count=get_subquery(Rack, 'role')
|
||||||
)
|
)
|
||||||
serializer_class = serializers.RackRoleSerializer
|
serializer_class = serializers.RackRoleSerializer
|
||||||
filterset_class = filters.RackRoleFilterSet
|
filterset_class = filters.RackRoleFilterSet
|
||||||
@ -167,8 +166,8 @@ class RackViewSet(CustomFieldModelViewSet):
|
|||||||
queryset = Rack.objects.prefetch_related(
|
queryset = Rack.objects.prefetch_related(
|
||||||
'site', 'group__site', 'role', 'tenant', 'tags'
|
'site', 'group__site', 'role', 'tenant', 'tags'
|
||||||
).annotate(
|
).annotate(
|
||||||
device_count=Coalesce(get_subquery(Device, 'rack'), 0),
|
device_count=get_subquery(Device, 'rack'),
|
||||||
powerfeed_count=Coalesce(get_subquery(PowerFeed, 'rack'), 0)
|
powerfeed_count=get_subquery(PowerFeed, 'rack')
|
||||||
)
|
)
|
||||||
serializer_class = serializers.RackSerializer
|
serializer_class = serializers.RackSerializer
|
||||||
filterset_class = filters.RackFilterSet
|
filterset_class = filters.RackFilterSet
|
||||||
@ -241,9 +240,9 @@ class RackReservationViewSet(ModelViewSet):
|
|||||||
|
|
||||||
class ManufacturerViewSet(ModelViewSet):
|
class ManufacturerViewSet(ModelViewSet):
|
||||||
queryset = Manufacturer.objects.annotate(
|
queryset = Manufacturer.objects.annotate(
|
||||||
devicetype_count=Coalesce(get_subquery(DeviceType, 'manufacturer'), 0),
|
devicetype_count=get_subquery(DeviceType, 'manufacturer'),
|
||||||
inventoryitem_count=Coalesce(get_subquery(InventoryItem, 'manufacturer'), 0),
|
inventoryitem_count=get_subquery(InventoryItem, 'manufacturer'),
|
||||||
platform_count=Coalesce(get_subquery(Platform, 'manufacturer'), 0)
|
platform_count=get_subquery(Platform, 'manufacturer')
|
||||||
)
|
)
|
||||||
serializer_class = serializers.ManufacturerSerializer
|
serializer_class = serializers.ManufacturerSerializer
|
||||||
filterset_class = filters.ManufacturerFilterSet
|
filterset_class = filters.ManufacturerFilterSet
|
||||||
@ -255,7 +254,7 @@ class ManufacturerViewSet(ModelViewSet):
|
|||||||
|
|
||||||
class DeviceTypeViewSet(CustomFieldModelViewSet):
|
class DeviceTypeViewSet(CustomFieldModelViewSet):
|
||||||
queryset = DeviceType.objects.prefetch_related('manufacturer', 'tags').annotate(
|
queryset = DeviceType.objects.prefetch_related('manufacturer', 'tags').annotate(
|
||||||
device_count=Coalesce(get_subquery(Device, 'device_type'), 0)
|
device_count=get_subquery(Device, 'device_type')
|
||||||
)
|
)
|
||||||
serializer_class = serializers.DeviceTypeSerializer
|
serializer_class = serializers.DeviceTypeSerializer
|
||||||
filterset_class = filters.DeviceTypeFilterSet
|
filterset_class = filters.DeviceTypeFilterSet
|
||||||
@ -319,8 +318,8 @@ class DeviceBayTemplateViewSet(ModelViewSet):
|
|||||||
|
|
||||||
class DeviceRoleViewSet(ModelViewSet):
|
class DeviceRoleViewSet(ModelViewSet):
|
||||||
queryset = DeviceRole.objects.annotate(
|
queryset = DeviceRole.objects.annotate(
|
||||||
device_count=Coalesce(get_subquery(Device, 'device_role'), 0),
|
device_count=get_subquery(Device, 'device_role'),
|
||||||
virtualmachine_count=Coalesce(get_subquery(VirtualMachine, 'role'), 0)
|
virtualmachine_count=get_subquery(VirtualMachine, 'role')
|
||||||
)
|
)
|
||||||
serializer_class = serializers.DeviceRoleSerializer
|
serializer_class = serializers.DeviceRoleSerializer
|
||||||
filterset_class = filters.DeviceRoleFilterSet
|
filterset_class = filters.DeviceRoleFilterSet
|
||||||
@ -332,8 +331,8 @@ class DeviceRoleViewSet(ModelViewSet):
|
|||||||
|
|
||||||
class PlatformViewSet(ModelViewSet):
|
class PlatformViewSet(ModelViewSet):
|
||||||
queryset = Platform.objects.annotate(
|
queryset = Platform.objects.annotate(
|
||||||
device_count=Coalesce(get_subquery(Device, 'platform'), 0),
|
device_count=get_subquery(Device, 'platform'),
|
||||||
virtualmachine_count=Coalesce(get_subquery(VirtualMachine, 'platform'), 0)
|
virtualmachine_count=get_subquery(VirtualMachine, 'platform')
|
||||||
)
|
)
|
||||||
serializer_class = serializers.PlatformSerializer
|
serializer_class = serializers.PlatformSerializer
|
||||||
filterset_class = filters.PlatformFilterSet
|
filterset_class = filters.PlatformFilterSet
|
||||||
@ -597,7 +596,7 @@ class CableViewSet(ModelViewSet):
|
|||||||
|
|
||||||
class VirtualChassisViewSet(ModelViewSet):
|
class VirtualChassisViewSet(ModelViewSet):
|
||||||
queryset = VirtualChassis.objects.prefetch_related('tags').annotate(
|
queryset = VirtualChassis.objects.prefetch_related('tags').annotate(
|
||||||
member_count=Coalesce(get_subquery(Device, 'virtual_chassis'), 0)
|
member_count=get_subquery(Device, 'virtual_chassis')
|
||||||
)
|
)
|
||||||
serializer_class = serializers.VirtualChassisSerializer
|
serializer_class = serializers.VirtualChassisSerializer
|
||||||
filterset_class = filters.VirtualChassisFilterSet
|
filterset_class = filters.VirtualChassisFilterSet
|
||||||
@ -611,7 +610,7 @@ class PowerPanelViewSet(ModelViewSet):
|
|||||||
queryset = PowerPanel.objects.prefetch_related(
|
queryset = PowerPanel.objects.prefetch_related(
|
||||||
'site', 'rack_group'
|
'site', 'rack_group'
|
||||||
).annotate(
|
).annotate(
|
||||||
powerfeed_count=Coalesce(get_subquery(PowerFeed, 'power_panel'), 0)
|
powerfeed_count=get_subquery(PowerFeed, 'power_panel')
|
||||||
)
|
)
|
||||||
serializer_class = serializers.PowerPanelSerializer
|
serializer_class = serializers.PowerPanelSerializer
|
||||||
filterset_class = filters.PowerPanelFilterSet
|
filterset_class = filters.PowerPanelFilterSet
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.db.models.functions import Coalesce
|
|
||||||
from django.http import Http404
|
from django.http import Http404
|
||||||
from django_rq.queues import get_connection
|
from django_rq.queues import get_connection
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
@ -103,7 +102,7 @@ class ExportTemplateViewSet(ModelViewSet):
|
|||||||
|
|
||||||
class TagViewSet(ModelViewSet):
|
class TagViewSet(ModelViewSet):
|
||||||
queryset = Tag.objects.annotate(
|
queryset = Tag.objects.annotate(
|
||||||
tagged_items=Coalesce(get_subquery(TaggedItem, 'tag'), 0)
|
tagged_items=get_subquery(TaggedItem, 'tag')
|
||||||
)
|
)
|
||||||
serializer_class = serializers.TagSerializer
|
serializer_class = serializers.TagSerializer
|
||||||
filterset_class = filters.TagFilterSet
|
filterset_class = filters.TagFilterSet
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db.models.functions import Coalesce
|
|
||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
from django_pglocks import advisory_lock
|
from django_pglocks import advisory_lock
|
||||||
from drf_yasg.utils import swagger_auto_schema
|
from drf_yasg.utils import swagger_auto_schema
|
||||||
@ -33,8 +32,8 @@ class VRFViewSet(CustomFieldModelViewSet):
|
|||||||
queryset = VRF.objects.prefetch_related('tenant').prefetch_related(
|
queryset = VRF.objects.prefetch_related('tenant').prefetch_related(
|
||||||
'import_targets', 'export_targets', 'tags'
|
'import_targets', 'export_targets', 'tags'
|
||||||
).annotate(
|
).annotate(
|
||||||
ipaddress_count=Coalesce(get_subquery(IPAddress, 'vrf'), 0),
|
ipaddress_count=get_subquery(IPAddress, 'vrf'),
|
||||||
prefix_count=Coalesce(get_subquery(Prefix, 'vrf'), 0)
|
prefix_count=get_subquery(Prefix, 'vrf')
|
||||||
)
|
)
|
||||||
serializer_class = serializers.VRFSerializer
|
serializer_class = serializers.VRFSerializer
|
||||||
filterset_class = filters.VRFFilterSet
|
filterset_class = filters.VRFFilterSet
|
||||||
@ -56,7 +55,7 @@ class RouteTargetViewSet(CustomFieldModelViewSet):
|
|||||||
|
|
||||||
class RIRViewSet(ModelViewSet):
|
class RIRViewSet(ModelViewSet):
|
||||||
queryset = RIR.objects.annotate(
|
queryset = RIR.objects.annotate(
|
||||||
aggregate_count=Coalesce(get_subquery(Aggregate, 'rir'), 0)
|
aggregate_count=get_subquery(Aggregate, 'rir')
|
||||||
)
|
)
|
||||||
serializer_class = serializers.RIRSerializer
|
serializer_class = serializers.RIRSerializer
|
||||||
filterset_class = filters.RIRFilterSet
|
filterset_class = filters.RIRFilterSet
|
||||||
@ -78,8 +77,8 @@ class AggregateViewSet(CustomFieldModelViewSet):
|
|||||||
|
|
||||||
class RoleViewSet(ModelViewSet):
|
class RoleViewSet(ModelViewSet):
|
||||||
queryset = Role.objects.annotate(
|
queryset = Role.objects.annotate(
|
||||||
prefix_count=Coalesce(get_subquery(Prefix, 'role'), 0),
|
prefix_count=get_subquery(Prefix, 'role'),
|
||||||
vlan_count=Coalesce(get_subquery(VLAN, 'role'), 0)
|
vlan_count=get_subquery(VLAN, 'role')
|
||||||
)
|
)
|
||||||
serializer_class = serializers.RoleSerializer
|
serializer_class = serializers.RoleSerializer
|
||||||
filterset_class = filters.RoleFilterSet
|
filterset_class = filters.RoleFilterSet
|
||||||
@ -273,7 +272,7 @@ class IPAddressViewSet(CustomFieldModelViewSet):
|
|||||||
|
|
||||||
class VLANGroupViewSet(ModelViewSet):
|
class VLANGroupViewSet(ModelViewSet):
|
||||||
queryset = VLANGroup.objects.prefetch_related('site').annotate(
|
queryset = VLANGroup.objects.prefetch_related('site').annotate(
|
||||||
vlan_count=Coalesce(get_subquery(VLAN, 'group'), 0)
|
vlan_count=get_subquery(VLAN, 'group')
|
||||||
)
|
)
|
||||||
serializer_class = serializers.VLANGroupSerializer
|
serializer_class = serializers.VLANGroupSerializer
|
||||||
filterset_class = filters.VLANGroupFilterSet
|
filterset_class = filters.VLANGroupFilterSet
|
||||||
@ -287,7 +286,7 @@ class VLANViewSet(CustomFieldModelViewSet):
|
|||||||
queryset = VLAN.objects.prefetch_related(
|
queryset = VLAN.objects.prefetch_related(
|
||||||
'site', 'group', 'tenant', 'role', 'tags'
|
'site', 'group', 'tenant', 'role', 'tags'
|
||||||
).annotate(
|
).annotate(
|
||||||
prefix_count=Coalesce(get_subquery(Prefix, 'vlan'), 0)
|
prefix_count=get_subquery(Prefix, 'vlan')
|
||||||
)
|
)
|
||||||
serializer_class = serializers.VLANSerializer
|
serializer_class = serializers.VLANSerializer
|
||||||
filterset_class = filters.VLANFilterSet
|
filterset_class = filters.VLANFilterSet
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import base64
|
import base64
|
||||||
|
|
||||||
from Crypto.PublicKey import RSA
|
from Crypto.PublicKey import RSA
|
||||||
from django.db.models.functions import Coalesce
|
|
||||||
from django.http import HttpResponseBadRequest
|
from django.http import HttpResponseBadRequest
|
||||||
from rest_framework.exceptions import ValidationError
|
from rest_framework.exceptions import ValidationError
|
||||||
from rest_framework.permissions import IsAuthenticated
|
from rest_framework.permissions import IsAuthenticated
|
||||||
@ -36,7 +35,7 @@ class SecretsRootView(APIRootView):
|
|||||||
|
|
||||||
class SecretRoleViewSet(ModelViewSet):
|
class SecretRoleViewSet(ModelViewSet):
|
||||||
queryset = SecretRole.objects.annotate(
|
queryset = SecretRole.objects.annotate(
|
||||||
secret_count=Coalesce(get_subquery(Secret, 'role'), 0)
|
secret_count=get_subquery(Secret, 'role')
|
||||||
)
|
)
|
||||||
serializer_class = serializers.SecretRoleSerializer
|
serializer_class = serializers.SecretRoleSerializer
|
||||||
filterset_class = filters.SecretRoleFilterSet
|
filterset_class = filters.SecretRoleFilterSet
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
from django.db.models.functions import Coalesce
|
|
||||||
from rest_framework.routers import APIRootView
|
from rest_framework.routers import APIRootView
|
||||||
|
|
||||||
from circuits.models import Circuit
|
from circuits.models import Circuit
|
||||||
@ -47,13 +46,13 @@ class TenantViewSet(CustomFieldModelViewSet):
|
|||||||
).annotate(
|
).annotate(
|
||||||
circuit_count=get_subquery(Circuit, 'tenant'),
|
circuit_count=get_subquery(Circuit, 'tenant'),
|
||||||
device_count=get_subquery(Device, 'tenant'),
|
device_count=get_subquery(Device, 'tenant'),
|
||||||
ipaddress_count=Coalesce(get_subquery(IPAddress, 'tenant'), 0),
|
ipaddress_count=get_subquery(IPAddress, 'tenant'),
|
||||||
prefix_count=Coalesce(get_subquery(Prefix, 'tenant'), 0),
|
prefix_count=get_subquery(Prefix, 'tenant'),
|
||||||
rack_count=Coalesce(get_subquery(Rack, 'tenant'), 0),
|
rack_count=get_subquery(Rack, 'tenant'),
|
||||||
site_count=Coalesce(get_subquery(Site, 'tenant'), 0),
|
site_count=get_subquery(Site, 'tenant'),
|
||||||
virtualmachine_count=Coalesce(get_subquery(VirtualMachine, 'tenant'), 0),
|
virtualmachine_count=get_subquery(VirtualMachine, 'tenant'),
|
||||||
vlan_count=Coalesce(get_subquery(VLAN, 'tenant'), 0),
|
vlan_count=get_subquery(VLAN, 'tenant'),
|
||||||
vrf_count=Coalesce(get_subquery(VRF, 'tenant'), 0)
|
vrf_count=get_subquery(VRF, 'tenant')
|
||||||
)
|
)
|
||||||
serializer_class = serializers.TenantSerializer
|
serializer_class = serializers.TenantSerializer
|
||||||
filterset_class = filters.TenantFilterSet
|
filterset_class = filters.TenantFilterSet
|
||||||
|
@ -5,6 +5,7 @@ from itertools import count, groupby
|
|||||||
|
|
||||||
from django.core.serializers import serialize
|
from django.core.serializers import serialize
|
||||||
from django.db.models import Count, OuterRef, Subquery
|
from django.db.models import Count, OuterRef, Subquery
|
||||||
|
from django.db.models.functions import Coalesce
|
||||||
from jinja2 import Environment
|
from jinja2 import Environment
|
||||||
|
|
||||||
from dcim.choices import CableLengthUnitChoices
|
from dcim.choices import CableLengthUnitChoices
|
||||||
@ -79,7 +80,7 @@ def get_subquery(model, field):
|
|||||||
).values('c')
|
).values('c')
|
||||||
)
|
)
|
||||||
|
|
||||||
return subquery
|
return Coalesce(subquery, 0)
|
||||||
|
|
||||||
|
|
||||||
def serialize_object(obj, extra=None, exclude=None):
|
def serialize_object(obj, extra=None, exclude=None):
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
from django.db.models.functions import Coalesce
|
|
||||||
from rest_framework.routers import APIRootView
|
from rest_framework.routers import APIRootView
|
||||||
|
|
||||||
from dcim.models import Device
|
from dcim.models import Device
|
||||||
@ -23,7 +22,7 @@ class VirtualizationRootView(APIRootView):
|
|||||||
|
|
||||||
class ClusterTypeViewSet(ModelViewSet):
|
class ClusterTypeViewSet(ModelViewSet):
|
||||||
queryset = ClusterType.objects.annotate(
|
queryset = ClusterType.objects.annotate(
|
||||||
cluster_count=Coalesce(get_subquery(Cluster, 'type'), 0)
|
cluster_count=get_subquery(Cluster, 'type')
|
||||||
)
|
)
|
||||||
serializer_class = serializers.ClusterTypeSerializer
|
serializer_class = serializers.ClusterTypeSerializer
|
||||||
filterset_class = filters.ClusterTypeFilterSet
|
filterset_class = filters.ClusterTypeFilterSet
|
||||||
@ -31,7 +30,7 @@ class ClusterTypeViewSet(ModelViewSet):
|
|||||||
|
|
||||||
class ClusterGroupViewSet(ModelViewSet):
|
class ClusterGroupViewSet(ModelViewSet):
|
||||||
queryset = ClusterGroup.objects.annotate(
|
queryset = ClusterGroup.objects.annotate(
|
||||||
cluster_count=Coalesce(get_subquery(Cluster, 'group'), 0)
|
cluster_count=get_subquery(Cluster, 'group')
|
||||||
)
|
)
|
||||||
serializer_class = serializers.ClusterGroupSerializer
|
serializer_class = serializers.ClusterGroupSerializer
|
||||||
filterset_class = filters.ClusterGroupFilterSet
|
filterset_class = filters.ClusterGroupFilterSet
|
||||||
@ -41,8 +40,8 @@ class ClusterViewSet(CustomFieldModelViewSet):
|
|||||||
queryset = Cluster.objects.prefetch_related(
|
queryset = Cluster.objects.prefetch_related(
|
||||||
'type', 'group', 'tenant', 'site', 'tags'
|
'type', 'group', 'tenant', 'site', 'tags'
|
||||||
).annotate(
|
).annotate(
|
||||||
device_count=Coalesce(get_subquery(Device, 'cluster'), 0),
|
device_count=get_subquery(Device, 'cluster'),
|
||||||
virtualmachine_count=Coalesce(get_subquery(VirtualMachine, 'cluster'), 0)
|
virtualmachine_count=get_subquery(VirtualMachine, 'cluster')
|
||||||
)
|
)
|
||||||
serializer_class = serializers.ClusterSerializer
|
serializer_class = serializers.ClusterSerializer
|
||||||
filterset_class = filters.ClusterFilterSet
|
filterset_class = filters.ClusterFilterSet
|
||||||
|
Reference in New Issue
Block a user