mirror of
https://github.com/netbox-community/netbox.git
synced 2025-12-09 01:49:35 -06:00
parent
20de263565
commit
f383067ecb
@ -3,12 +3,12 @@ from typing import Annotated, List, TYPE_CHECKING
|
|||||||
import strawberry
|
import strawberry
|
||||||
import strawberry_django
|
import strawberry_django
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
|
from strawberry.types import Info
|
||||||
|
|
||||||
from core.models import ObjectChange
|
from core.models import ObjectChange
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from core.graphql.types import DataFileType, DataSourceType
|
from core.graphql.types import DataFileType, DataSourceType, ObjectChangeType
|
||||||
from netbox.core.graphql.types import ObjectChangeType
|
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'ChangelogMixin',
|
'ChangelogMixin',
|
||||||
@ -20,7 +20,7 @@ __all__ = (
|
|||||||
class ChangelogMixin:
|
class ChangelogMixin:
|
||||||
|
|
||||||
@strawberry_django.field
|
@strawberry_django.field
|
||||||
def changelog(self, info) -> List[Annotated["ObjectChangeType", strawberry.lazy('.types')]]: # noqa: F821
|
def changelog(self, info: Info) -> List[Annotated['ObjectChangeType', strawberry.lazy('.types')]]: # noqa: F821
|
||||||
content_type = ContentType.objects.get_for_model(self)
|
content_type = ContentType.objects.get_for_model(self)
|
||||||
object_changes = ObjectChange.objects.filter(
|
object_changes = ObjectChange.objects.filter(
|
||||||
changed_object_type=content_type,
|
changed_object_type=content_type,
|
||||||
@ -31,5 +31,5 @@ class ChangelogMixin:
|
|||||||
|
|
||||||
@strawberry.type
|
@strawberry.type
|
||||||
class SyncedDataMixin:
|
class SyncedDataMixin:
|
||||||
data_source: Annotated["DataSourceType", strawberry.lazy('core.graphql.types')] | None
|
data_source: Annotated['DataSourceType', strawberry.lazy('core.graphql.types')] | None
|
||||||
data_file: Annotated["DataFileType", strawberry.lazy('core.graphql.types')] | None
|
data_file: Annotated['DataFileType', strawberry.lazy('core.graphql.types')] | None
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
from strawberry.types import Info
|
||||||
|
|
||||||
from circuits.graphql.types import CircuitTerminationType, ProviderNetworkType
|
from circuits.graphql.types import CircuitTerminationType, ProviderNetworkType
|
||||||
from circuits.models import CircuitTermination, ProviderNetwork
|
from circuits.models import CircuitTermination, ProviderNetwork
|
||||||
from dcim.graphql.types import (
|
from dcim.graphql.types import (
|
||||||
@ -49,7 +51,7 @@ class InventoryItemTemplateComponentType:
|
|||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def resolve_type(cls, instance, info):
|
def resolve_type(cls, instance, info: Info):
|
||||||
if type(instance) is ConsolePortTemplate:
|
if type(instance) is ConsolePortTemplate:
|
||||||
return ConsolePortTemplateType
|
return ConsolePortTemplateType
|
||||||
if type(instance) is ConsoleServerPortTemplate:
|
if type(instance) is ConsoleServerPortTemplate:
|
||||||
@ -79,7 +81,7 @@ class InventoryItemComponentType:
|
|||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def resolve_type(cls, instance, info):
|
def resolve_type(cls, instance, info: Info):
|
||||||
if type(instance) is ConsolePort:
|
if type(instance) is ConsolePort:
|
||||||
return ConsolePortType
|
return ConsolePortType
|
||||||
if type(instance) is ConsoleServerPort:
|
if type(instance) is ConsoleServerPort:
|
||||||
@ -112,7 +114,7 @@ class ConnectedEndpointType:
|
|||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def resolve_type(cls, instance, info):
|
def resolve_type(cls, instance, info: Info):
|
||||||
if type(instance) is CircuitTermination:
|
if type(instance) is CircuitTermination:
|
||||||
return CircuitTerminationType
|
return CircuitTerminationType
|
||||||
if type(instance) is ConsolePortType:
|
if type(instance) is ConsolePortType:
|
||||||
|
|||||||
@ -196,7 +196,7 @@ class DeviceTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
|
|||||||
verbose_name=_('Type')
|
verbose_name=_('Type')
|
||||||
)
|
)
|
||||||
u_height = columns.TemplateColumn(
|
u_height = columns.TemplateColumn(
|
||||||
accessor=tables.A('device_type.u_height'),
|
accessor=tables.A('device_type__u_height'),
|
||||||
verbose_name=_('U Height'),
|
verbose_name=_('U Height'),
|
||||||
template_code='{{ value|floatformat }}'
|
template_code='{{ value|floatformat }}'
|
||||||
)
|
)
|
||||||
|
|||||||
@ -2,6 +2,7 @@ from typing import TYPE_CHECKING, Annotated, List
|
|||||||
|
|
||||||
import strawberry
|
import strawberry
|
||||||
import strawberry_django
|
import strawberry_django
|
||||||
|
from strawberry.types import Info
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'ConfigContextMixin',
|
'ConfigContextMixin',
|
||||||
@ -37,7 +38,7 @@ class CustomFieldsMixin:
|
|||||||
class ImageAttachmentsMixin:
|
class ImageAttachmentsMixin:
|
||||||
|
|
||||||
@strawberry_django.field
|
@strawberry_django.field
|
||||||
def image_attachments(self, info) -> List[Annotated["ImageAttachmentType", strawberry.lazy('.types')]]:
|
def image_attachments(self, info: Info) -> List[Annotated['ImageAttachmentType', strawberry.lazy('.types')]]:
|
||||||
return self.images.restrict(info.context.request.user, 'view')
|
return self.images.restrict(info.context.request.user, 'view')
|
||||||
|
|
||||||
|
|
||||||
@ -45,17 +46,17 @@ class ImageAttachmentsMixin:
|
|||||||
class JournalEntriesMixin:
|
class JournalEntriesMixin:
|
||||||
|
|
||||||
@strawberry_django.field
|
@strawberry_django.field
|
||||||
def journal_entries(self, info) -> List[Annotated["JournalEntryType", strawberry.lazy('.types')]]:
|
def journal_entries(self, info: Info) -> List[Annotated['JournalEntryType', strawberry.lazy('.types')]]:
|
||||||
return self.journal_entries.all()
|
return self.journal_entries.all()
|
||||||
|
|
||||||
|
|
||||||
@strawberry.type
|
@strawberry.type
|
||||||
class TagsMixin:
|
class TagsMixin:
|
||||||
|
|
||||||
tags: List[Annotated["TagType", strawberry.lazy('.types')]]
|
tags: List[Annotated['TagType', strawberry.lazy('.types')]]
|
||||||
|
|
||||||
|
|
||||||
@strawberry.type
|
@strawberry.type
|
||||||
class ContactsMixin:
|
class ContactsMixin:
|
||||||
|
|
||||||
contacts: List[Annotated["ContactAssignmentType", strawberry.lazy('tenancy.graphql.types')]]
|
contacts: List[Annotated['ContactAssignmentType', strawberry.lazy('tenancy.graphql.types')]]
|
||||||
|
|||||||
@ -90,7 +90,7 @@ class ConfigContextModelQuerySet(RestrictedQuerySet):
|
|||||||
ConfigContext.objects.filter(
|
ConfigContext.objects.filter(
|
||||||
self._get_config_context_filters()
|
self._get_config_context_filters()
|
||||||
).annotate(
|
).annotate(
|
||||||
_data=EmptyGroupByJSONBAgg('data', ordering=['weight', 'name'])
|
_data=EmptyGroupByJSONBAgg('data', order_by=['weight', 'name'])
|
||||||
).values("_data").order_by()
|
).values("_data").order_by()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@ -7,6 +7,7 @@ from django.core.exceptions import FieldDoesNotExist
|
|||||||
from django.db.models import Q, QuerySet
|
from django.db.models import Q, QuerySet
|
||||||
from django.db.models.fields.related import ForeignKey, ManyToManyField, ManyToManyRel, ManyToOneRel
|
from django.db.models.fields.related import ForeignKey, ManyToManyField, ManyToManyRel, ManyToOneRel
|
||||||
from strawberry import ID
|
from strawberry import ID
|
||||||
|
from strawberry.directive import DirectiveValue
|
||||||
from strawberry.types import Info
|
from strawberry.types import Info
|
||||||
from strawberry_django import (
|
from strawberry_django import (
|
||||||
ComparisonFilterLookup,
|
ComparisonFilterLookup,
|
||||||
@ -68,7 +69,7 @@ class IntegerLookup:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
@strawberry_django.filter_field
|
@strawberry_django.filter_field
|
||||||
def filter(self, info: Info, queryset: QuerySet, prefix: str = '') -> Tuple[QuerySet, Q]:
|
def filter(self, info: Info, queryset: QuerySet, prefix: DirectiveValue[str] = '') -> Tuple[QuerySet, Q]:
|
||||||
filters = self.get_filter()
|
filters = self.get_filter()
|
||||||
|
|
||||||
if not filters:
|
if not filters:
|
||||||
@ -91,7 +92,7 @@ class FloatLookup:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
@strawberry_django.filter_field
|
@strawberry_django.filter_field
|
||||||
def filter(self, info: Info, queryset: QuerySet, prefix: str = '') -> Tuple[QuerySet, Q]:
|
def filter(self, info: Info, queryset: QuerySet, prefix: DirectiveValue[str] = '') -> Tuple[QuerySet, Q]:
|
||||||
filters = self.get_filter()
|
filters = self.get_filter()
|
||||||
|
|
||||||
if not filters:
|
if not filters:
|
||||||
@ -110,7 +111,7 @@ class JSONFilter:
|
|||||||
lookup: JSONLookup
|
lookup: JSONLookup
|
||||||
|
|
||||||
@strawberry_django.filter_field
|
@strawberry_django.filter_field
|
||||||
def filter(self, info: Info, queryset: QuerySet, prefix: str = '') -> Tuple[QuerySet, Q]:
|
def filter(self, info: Info, queryset: QuerySet, prefix: DirectiveValue[str] = '') -> Tuple[QuerySet, Q]:
|
||||||
filters = self.lookup.get_filter()
|
filters = self.lookup.get_filter()
|
||||||
|
|
||||||
if not filters:
|
if not filters:
|
||||||
@ -137,7 +138,7 @@ class TreeNodeFilter:
|
|||||||
match_type: TreeNodeMatch
|
match_type: TreeNodeMatch
|
||||||
|
|
||||||
@strawberry_django.filter_field
|
@strawberry_django.filter_field
|
||||||
def filter(self, info: Info, queryset: QuerySet, prefix: str = '') -> Tuple[QuerySet, Q]:
|
def filter(self, info: Info, queryset: QuerySet, prefix: DirectiveValue[str] = '') -> Tuple[QuerySet, Q]:
|
||||||
model_field_name = prefix.removesuffix('__').removesuffix('_id')
|
model_field_name = prefix.removesuffix('__').removesuffix('_id')
|
||||||
model_field = None
|
model_field = None
|
||||||
try:
|
try:
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import strawberry
|
import strawberry
|
||||||
import strawberry_django
|
import strawberry_django
|
||||||
|
from strawberry.types import Info
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
|
|
||||||
from core.graphql.mixins import ChangelogMixin
|
from core.graphql.mixins import ChangelogMixin
|
||||||
@ -26,7 +27,7 @@ class BaseObjectType:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_queryset(cls, queryset, info, **kwargs):
|
def get_queryset(cls, queryset, info: Info, **kwargs):
|
||||||
# Enforce object permissions on the queryset
|
# Enforce object permissions on the queryset
|
||||||
if hasattr(queryset, 'restrict'):
|
if hasattr(queryset, 'restrict'):
|
||||||
return queryset.restrict(info.context.request.user, 'view')
|
return queryset.restrict(info.context.request.user, 'view')
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
from django import forms
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
@ -25,7 +26,7 @@ class TenantGroupImportForm(NetBoxModelImportForm):
|
|||||||
queryset=TenantGroup.objects.all(),
|
queryset=TenantGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
to_field_name='name',
|
to_field_name='name',
|
||||||
help_text=_('Parent group')
|
help_text=_('Parent group'),
|
||||||
)
|
)
|
||||||
slug = SlugField()
|
slug = SlugField()
|
||||||
|
|
||||||
@ -41,7 +42,7 @@ class TenantImportForm(NetBoxModelImportForm):
|
|||||||
queryset=TenantGroup.objects.all(),
|
queryset=TenantGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
to_field_name='name',
|
to_field_name='name',
|
||||||
help_text=_('Assigned group')
|
help_text=_('Assigned group'),
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -59,7 +60,7 @@ class ContactGroupImportForm(NetBoxModelImportForm):
|
|||||||
queryset=ContactGroup.objects.all(),
|
queryset=ContactGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
to_field_name='name',
|
to_field_name='name',
|
||||||
help_text=_('Parent group')
|
help_text=_('Parent group'),
|
||||||
)
|
)
|
||||||
slug = SlugField()
|
slug = SlugField()
|
||||||
|
|
||||||
@ -81,7 +82,12 @@ class ContactImportForm(NetBoxModelImportForm):
|
|||||||
queryset=ContactGroup.objects.all(),
|
queryset=ContactGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
to_field_name='name',
|
to_field_name='name',
|
||||||
help_text=_('Group names separated by commas, encased with double quotes (e.g. "Group 1,Group 2")')
|
help_text=_('Group names separated by commas, encased with double quotes (e.g. "Group 1,Group 2")'),
|
||||||
|
)
|
||||||
|
link = forms.URLField(
|
||||||
|
label=_('Link'),
|
||||||
|
assume_scheme='https',
|
||||||
|
required=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|||||||
@ -100,6 +100,11 @@ class ContactForm(NetBoxModelForm):
|
|||||||
queryset=ContactGroup.objects.all(),
|
queryset=ContactGroup.objects.all(),
|
||||||
required=False
|
required=False
|
||||||
)
|
)
|
||||||
|
link = forms.URLField(
|
||||||
|
label=_('Link'),
|
||||||
|
assume_scheme='https',
|
||||||
|
required=False,
|
||||||
|
)
|
||||||
comments = CommentField()
|
comments = CommentField()
|
||||||
|
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user