15156 review changes

This commit is contained in:
Arthur Hanson 2024-06-14 13:51:14 -07:00
parent 57ead66e7a
commit 46d45b1f18

View File

@ -13,27 +13,49 @@ __all__ = (
) )
class NetBoxAPIHyperlinkedIdentityField(serializers.HyperlinkedIdentityField): class BaseNetBoxHyperlinkedIdentityField(serializers.HyperlinkedIdentityField):
"""
Overrides HyperlinkedIdentityField to use standard NetBox view naming
instead of passing in the view_name. Initialize with a blank view_name
and it will get replaced in the get_url call. Derived classes must
define a get_view_name.
"""
def get_url(self, obj, view_name, request, format):
"""
Given an object, return the URL that hyperlinks to the object.
def __init__(self, model, **kwargs): May raise a `NoReverseMatch` if the `view_name` and `lookup_field`
model_name = model._meta.model_name attributes are not configured to correctly match the URL conf.
app_name = model._meta.app_label """
view_name = f'{app_name}-api:{model_name}-detail' # Unsaved objects will not yet have a valid URL.
super().__init__(view_name, **kwargs) if hasattr(obj, 'pk') and obj.pk in (None, ''):
return None
lookup_value = getattr(obj, self.lookup_field)
kwargs = {self.lookup_url_kwarg: lookup_value}
model_name = self.parent.Meta.model._meta.model_name
app_name = self.parent.Meta.model._meta.app_label
view_name = self.get_view_name(app_name, model_name)
return self.reverse(view_name, kwargs=kwargs, request=request, format=format)
class NetBoxURLHyperlinkedIdentityField(serializers.HyperlinkedIdentityField): class NetBoxAPIHyperlinkedIdentityField(BaseNetBoxHyperlinkedIdentityField):
def __init__(self, model, **kwargs): def get_view_name(self, app_name, model_name):
model_name = model._meta.model_name return f'{app_name}-api:{model_name}-detail'
app_name = model._meta.app_label
view_name = f'{app_name}:{model_name}'
super().__init__(view_name, **kwargs)
class NetBoxURLHyperlinkedIdentityField(BaseNetBoxHyperlinkedIdentityField):
def get_view_name(self, app_name, model_name):
return f'{app_name}:{model_name}'
class BaseModelSerializer(serializers.ModelSerializer): class BaseModelSerializer(serializers.ModelSerializer):
url = serializers.RelatedField(read_only=True) url = NetBoxAPIHyperlinkedIdentityField(view_name="")
display_url = serializers.RelatedField(read_only=True) display_url = NetBoxURLHyperlinkedIdentityField(view_name="")
display = serializers.SerializerMethodField(read_only=True) display = serializers.SerializerMethodField(read_only=True)
def __init__(self, *args, nested=False, fields=None, **kwargs): def __init__(self, *args, nested=False, fields=None, **kwargs):
@ -56,15 +78,6 @@ class BaseModelSerializer(serializers.ModelSerializer):
if self.nested and not fields: if self.nested and not fields:
self._requested_fields = getattr(self.Meta, 'brief_fields', None) self._requested_fields = getattr(self.Meta, 'brief_fields', None)
# don't override the field if the class already defines these so can set lookup_field
if ("url" in self.fields and not isinstance(self.fields["url"], serializers.HyperlinkedIdentityField) and
isinstance(self.fields["url"], serializers.RelatedField)):
self.fields["url"] = NetBoxAPIHyperlinkedIdentityField(self.Meta.model)
if ("display_url" in self.fields and not
isinstance(self.fields["display_url"], serializers.HyperlinkedIdentityField) and
isinstance(self.fields["display_url"], serializers.RelatedField)):
self.fields["display_url"] = NetBoxURLHyperlinkedIdentityField(self.Meta.model)
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
def to_internal_value(self, data): def to_internal_value(self, data):