-
Notifications
You must be signed in to change notification settings - Fork 253
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Replace NestedFooSerializer
and ?brief=True
parameters using DRF's built-in self.Meta.depth
#3500
Conversation
nautobot/core/api/serializers.py
Outdated
def build_nested_field(self, field_name, relation_info, nested_depth): | ||
field = get_serializer_for_model(relation_info.related_model) | ||
|
||
class NautobotNestedSerializer(field): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This class logic looks really similar to NautobotPrimaryKeyRelatedField
above, I guess finding a way to utitlize that class here might be a better approach
…tedTagSerailizer and TagSerializerField
…penAPISchema Serializer depth default to 1
What is going to be the overall change on this. What is the goal, what should be tested in SDKs? |
Some discussion points that will be coming up. From my viewpoint, whether there is a default depth of 0 or 1 isn't really a big deal. I like the brevity that comes with 0, just need to make sure that the novel pynautobot and Nautobot API user know how to work with it. From my standpoint, if the default is 0, pynautobot would remain having the default be passed in, and provide a mechanism to set the depth on the calls within the instance create time. The Nautobot Ansible modules would create the instance with a depth of 1 to get at the same nested serializer data that is coming along. So if there is a vote, I'm a vote for a depth of 0 as default, and that the SDKs take care of providing sane default (Ansible) and access to the system. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚤 🐎 ⏩
nautobot/virtualization/forms.py
Outdated
@@ -453,7 +453,7 @@ class VMInterfaceForm(NautobotModelForm, InterfaceCommonForm): | |||
queryset=VLAN.objects.all(), | |||
required=False, | |||
label="Untagged VLAN", | |||
brief_mode=False, | |||
depth=1, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See my other comments, I don't think this is in fact correct/necessary in the vast majority of cases.
nautobot/core/api/serializers.py
Outdated
field_name == "tags" | ||
and isinstance(model_class.tags, (_NautobotTaggableManager, _TaggableManager)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably just the isinstance check is sufficient here - I think even if we had a _TaggableManager field named something other than tags
we'd still need this case?
@@ -315,3 +425,194 @@ class BulkOperationIntegerIDSerializer(serializers.Serializer): | |||
class GraphQLAPISerializer(serializers.Serializer): | |||
query = serializers.CharField(required=True, help_text="GraphQL query") | |||
variables = serializers.JSONField(required=False, help_text="Variables in JSON Format") | |||
|
|||
|
|||
class CustomFieldModelSerializerMixin(ValidatedModelSerializer): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: should this be in nautobot.core.api.mixins
instead?
pass | ||
|
||
|
||
class RelationshipModelSerializerMixin(ValidatedModelSerializer): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: move to nautobot.core.api.mixins
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did try that before, however ValidatedModelSerializer
and BaseModelSerializer
base classes for these mixins seem to create another circular import problem🫠
return fields | ||
|
||
|
||
class NotesSerializerMixin(BaseModelSerializer): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: move to nautobot.core.api.mixins
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment above
nautobot/core/api/utils.py
Outdated
in which relation_info and nested_depth are already given. | ||
""" | ||
nested_serializer_name = ( | ||
"Nested" + str(nested_depth) + f"{relation_info.related_model._meta.model_name.capitalize()}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possibly?
"Nested" + str(nested_depth) + f"{relation_info.related_model._meta.model_name.capitalize()}" | |
f"Nested{nested_depth}{relation_info.related_model.__name__}" |
@extend_schema_field(NestedDeviceSerializer) | ||
def get_parent_device(self, obj): | ||
@extend_schema_field(DeviceBaySerializer) | ||
def get_parent_bay(self, obj): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to document this as an API change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added as an entry in v2-api-renamed-fields.yaml
nautobot/dcim/api/serializers.py
Outdated
context = {"request": self.context["request"]} | ||
data = NestedDeviceSerializer(instance=device_bay.device, context=context).data | ||
data["device_bay"] = NestedDeviceBaySerializer(instance=device_bay, context=context).data | ||
depth = int(self.context.get("depth", 0)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll be honest, I still don't fully understand this. :-) I see where Meta.depth
is decremented when we create a nested serializer, but I don't see where context["depth"]
does this. So it seems like with this code as-is, a query with depth=1
would result in the Device serializer rendering with depth 1, the nested device-bay serializer rendering with depth 1, its nested device serializer rendering with depth 1, its own nested device-bay serializer rendering with depth 1, etc. to infinite depth. But obviously that isn't happening... so what am I missing? :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚢 🇮🇹, I say !
|
||
def get_queryset_filter_params(self, data, queryset): | ||
""" | ||
Data could be a dictionary and an int (for the User model) or a str that represents the primary key. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dictionary and an int? It's not clear to me what that means.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It could be {"location": location.pk}
or a nested dictionary {"location": {"name": "Campus-01"}}
params = dict_to_filter_params(data) | ||
return self.remove_non_filter_fields(params) | ||
try: | ||
pk = int(data) if isinstance(queryset.model._meta.pk, AutoField) else uuid.UUID(str(data)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why casting data
to a UUID in the latter case? UUIDs can be strings. Are you just trying to force the error to assert that it must be either an int or UUID? If so can you please add a brief comment as to the intent here for posterity?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe the int
case is for the User
model mentioned in the docstring above. But yeah I can add a comment here as well.
@@ -128,6 +128,10 @@ These endpoints `/ipam/roles/`, `/dcim/rack-roles/` and `/dcim/device-roles/` ar | |||
| `/dcim/rack-roles/` | `/extras/roles/` | | |||
| `/ipam/roles/` | `/extras/roles/` | | |||
|
|||
### API Query Parameters Changes | |||
|
|||
Nautobot 2.0 removes the `?brief` query parameter and adds support for the `?depth` query parameter. As a result, the ability to specify `brief_mode` in `DynamicModelChoiceField` , `DynamicModelMultipleChoiceField` or `MultiMatchModelMultipleChoiceField` is also removed. For every occurrence of the aforementioned fields where you have `brief_mode` set to `True/False` e.g. `brief_mode=True`, please remove the statement. And leave other occurrences of the fields where you do not have `brief_mode` specified as they are. See more details about the `?depth` query parameter [here](../rest-api/overview.md/#depth-query-parameter) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should never link anything in documentation using "here". Better to always link the contextual text.
Nautobot 2.0 removes the `?brief` query parameter and adds support for the `?depth` query parameter. As a result, the ability to specify `brief_mode` in `DynamicModelChoiceField` , `DynamicModelMultipleChoiceField` or `MultiMatchModelMultipleChoiceField` is also removed. For every occurrence of the aforementioned fields where you have `brief_mode` set to `True/False` e.g. `brief_mode=True`, please remove the statement. And leave other occurrences of the fields where you do not have `brief_mode` specified as they are. See more details about the `?depth` query parameter [here](../rest-api/overview.md/#depth-query-parameter) | |
Nautobot 2.0 removes the `?brief` query parameter and adds support for the `?depth` query parameter. As a result, the ability to specify `brief_mode` in `DynamicModelChoiceField`, `DynamicModelMultipleChoiceField`, and `MultiMatchModelMultipleChoiceField` has also been removed. For every occurrence of the aforementioned fields where you have `brief_mode` set to `True/False` (e.g. `brief_mode=True`), please remove the statement, leaving other occurrences of the fields where you do not have `brief_mode` specified as they are. | |
Please see the [documentation on the `?depth` query parameter](../rest-api/overview.md/#depth-query-parameter) for more information. |
@@ -62,9 +62,9 @@ Any model form that is intended to have a `status` field must inherit from one o | |||
|
|||
- FIXME: CSV import forms | |||
|
|||
### `StatusModelSerializerMixin` serializer mixin | |||
### `` serializer mixin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like a typo? Also everything below appears to be in bold now?
@@ -98,7 +98,7 @@ To fully integrate a model to include a `status` field, assert the following: | |||
|
|||
### Serializers | |||
|
|||
- Serializers for your model must inherit from `nautobot.extras.api.serializers.StatusModelSerializerMixin` | |||
- Serializers for your model must inherit from `nautobot.extras.api.serializers.` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bad search/replace?
@@ -18,6 +18,10 @@ DeviceRole, RackRole, IPAM Role, and IPAddressRoleChoices have all been merged i | |||
|
|||
Added Site Model Fields to Location. Location Model now has `asn`, `comments`, `contact_email`, `contact_name`, `contact_phone`, `facility`, `latitude`, `longitude`, `physical_address`, `shipping_address` and `time_zone` fields. | |||
|
|||
#### Added Depth REST API Query Parameter | |||
|
|||
Added the `?depth` query parameter in Nautobot v2.X to replace the `?brief` parameter in the REST API. It enables [nested serialization](https://www.django-rest-framework.org/api-guide/serializers/#specifying-nested-serialization) functionality and offers a more dynamic and comprehensive browsable API. It allows users greater control of the API response data and it is available for both retrieving a single object and a list of objects. This parameter is an positive integer value that can range from 0 to 10. Check out more about the `?depth` query parameter in our [REST API Documentation](../rest-api/overview.md/#depth-query-parameter) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added the `?depth` query parameter in Nautobot v2.X to replace the `?brief` parameter in the REST API. It enables [nested serialization](https://www.django-rest-framework.org/api-guide/serializers/#specifying-nested-serialization) functionality and offers a more dynamic and comprehensive browsable API. It allows users greater control of the API response data and it is available for both retrieving a single object and a list of objects. This parameter is an positive integer value that can range from 0 to 10. Check out more about the `?depth` query parameter in our [REST API Documentation](../rest-api/overview.md/#depth-query-parameter) | |
Added the `?depth` query parameter in Nautobot v2.X to replace the `?brief` parameter in the REST API. It enables [nested serialization](https://www.django-rest-framework.org/api-guide/serializers/#specifying-nested-serialization) functionality and offers a more dynamic and comprehensive browsable API. It allows users greater control of the API response data and it is available for both retrieving a single object and a list of objects. This parameter is a positive integer value that can range from 0 to 10. To learn more more, check out the [documentation on the `?depth` query parameter](../rest-api/overview.md/#depth-query-parameter). |
@@ -236,6 +240,10 @@ The "Container" status will be removed and all prefixes will be migrated to the | |||
|
|||
### Removed | |||
|
|||
#### Removed Brief REST API Query Parameter | |||
|
|||
Support for `?brief` REST API query parameter and `Nested*Serializers` are being removed in Nautobot v2.X. They are replaced by the new `?depth` query parameter. Check out the specific changes in [REST API documentation](../rest-api/overview.md/#depth-query-parameter) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Support for `?brief` REST API query parameter and `Nested*Serializers` are being removed in Nautobot v2.X. They are replaced by the new `?depth` query parameter. Check out the specific changes in [REST API documentation](../rest-api/overview.md/#depth-query-parameter) | |
Support for `?brief` REST API query parameter and `Nested*Serializers` have been removed in Nautobot v2.X. They are replaced by the new [`?depth` query parameter](../rest-api/overview.md/#depth-query-parameter). |
// DynamicGroupSerializer has a `children` field which fits an inappropriate if condition | ||
// in select2.min.js, which will result in the incorrect rendering of DynamicGroup DynamicChoiceField. | ||
// So we nullify the field here since we do not need this field. | ||
if (record.url.includes("dynamic-groups")){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't wait to yeet this in v2 UI.
Closes: #3042
What's Changed
Remaining Items
extra_fields
inclass Meta
of the serializers?depth
in OpenAPI Schemabrief
testing functionalityTokenSerializer
whetheruser
field is a required field or not.primary_ip
andlocation
fields are not inherent fields (how to solve this)cluster_count
is missing fromTenantSerializer
in next and developobj.cluster.location
Location Browsable API
?depth=0 / default depth
?depth = 1
?depth = 2
too much info to fit on one screen but notice thatparent's
parent
is expanded as wellTODO