NautobotUIViewSet¶
Added in version 1.4.0
New in Nautobot 1.4 is the debut of NautobotUIViewSet: A powerful app development tool that can save app developer hundreds of lines of code compared to using legacy generic.views. Using it to gain access to default functionalities previous provided by generic.views such as create(), bulk_create(), update(), partial_update(), bulk_update(), destroy(), bulk_destroy(), retrieve() and list() actions.
Note that this ViewSet is catered specifically to the UI, not the API.
Concrete examples on how to use NautobotUIViewSet resides in nautobot.circuits.views.
Below we provide an example on how to use NautobotUIViewSet on a theoretical app model.
from nautobot.apps.views import NautobotUIViewSet
from yourapp import filters, forms, models, tables
from yourapp.api import serializers
class YourAppModelUIViewSet(NautobotUIViewSet):
bulk_update_form_class = forms.YourAppModelBulkEditForm
filterset_class = filters.YourAppModelFilterSet
filterset_form_class = forms.YourAppModelFilterForm
form_class = forms.YourAppModelForm
queryset = models.YourAppModel.objects.all()
serializer_class = serializers.YourAppModelSerializer
table_class = tables.YourAppModelTable
Setting ViewSet Attributes¶
One caveat of using the NautobotUIViewSet is that the queryset, serializer_class and table_class attribute of the YourAppModelUIViewSet has to be set before most of the NautobotUIViewSet functionalities will become available.
By default the URL patterns generated by a NautobotUIViewSet are based on the model's pk (/model-name/<pk>/ for the detail view, /model-name/<pk>/edit/ for the edit view, etc.). if you need to use a different field to look up an object, just override the default lookup_field in your ViewSet attributes:
from nautobot.apps.views import NautobotUIViewSet
class YourAppModelUIViewSet(NautobotUIViewSet):
...
lookup_field = "slug"
...
Changed in version 2.0.0
The default lookup_field for NautobotUIViewSet has been changed from "slug" to "pk".
Note
Using a field other than the default pk or the alternative field slug (as shown in the example above), may result in certain pieces of the UI not displaying (for example, the edit and delete buttons on the object detail view). This is due to the URL expecting a named key of slug or pk, rather than id.
View Template Context¶
Templates can benefit from a very rich context passed down from the views and renderer, including forms, tables, as well as any other information that may be helpful for rendering templates. The keys it provides are as follows:
content_type: The ContentType object for the associated modelfilter_form: The FilterForm object for the associated modelform: A Form object for the associated model if relevant (Nonefor list and detail/retrieve views)object: An instance of the associated mode if available (Nonefor list and bulk operation views)permissions: Summary of user permissions for the given modelreturn_url: The relevant return URLtable: A Table object for the associated model if relevant (Nonefor detail/retrieve and update views)table_config_form: A TableConfigForm object for the associatedtable, providing the ability to customize the tableverbose_name: The singular form of the model's nameverbose_name_plural: The plural form of the model's name
An example from editing a Provider object:
{
'content_type': <ContentType: circuits | provider>,
'filter_form': <ProviderFilterForm bound=True, valid=Unknown, fields=(location;q;asn;tag)>,
'form': <ProviderForm bound=False, valid=Unknown, fields=(name;asn;account;portal_url;noc_contact;admin_contact;comments;tags;object_note)>,
'object': <Provider: NautobotProvider>,
'permissions': {'add': True, 'change': True, 'delete': True, 'view': True},
'return_url': '/circuits/providers/nautobotprovider',
'table': None,
'table_config_form': None,
'verbose_name': 'provider',
'verbose_name_plural': 'providers'
}
Other context keys may be available for certain views:
editing: Provided for create and update views to help the template determine if this is a new or existing objectaction_buttons: Provided for the list view for the top of table buttons (such as "Add" and "Export")
You may see other context keys as well, but any not documented above should not be relied upon as they may be removed in a future release. Some examples of those are:
obj: Please useobjectinsteadobj_type: Please useverbose_nameinsteadobj_type_plural: Please useverbose_name_pluralinstead
Removed in version 2.0.0
The changelog_url context key was removed. Use object.get_changelog_url instead.
Excluding ViewMixins from NautobotUIViewSet¶
For app models that do not require certain views, simply inherit directly from the ViewMixin classes available in nautobot.apps.views instead of NautobotUIViewSet.
Concrete examples for excluding ViewMixins, checkout CircuitTerminationUIViewSet and CircuitTypeUIViewSet in nautobot.circuits.views.
## An app model viewset that does not support bulk views and operations
import nautobot.apps.views
class YourAppModelUIViewSet(
nautobot.apps.views.ObjectListViewMixin,
nautobot.apps.views.ObjectDetailViewMixin,
nautobot.apps.views.ObjectEditViewMixin,
nautobot.apps.views.ObjectDestroyViewMixin,
):
filterset_class = YourAppModelFilterSet
filterset_form_class = YourAppModelFilterForm
form_class = YourAppModelForm
queryset = YourAppModel.objects.all()
serializer_class = serializers.YourAppModelSerializer
table_class = YourAppModelTable
# You do not need to specify attributes that are not needed.
Excluding unwanted urls from NautobotUIViewSetRouter is done for you at the ViewSet level. If you do not inherit the unwanted ViewMixins, the corresponding route from the router will not be published.
# urls.py
# All the urls correspond to BulkViewMixins will not be published when you register your ViewSet with the router.
router.register("yourappmodel", views.YourAppModelUIViewSet)
Template Naming for NautobotUIViewSet¶
Template naming is very intuitive in NautobotUIViewSet. In templates/yourapp folder, name your templates following the convention {model_name}_{action}.html.
| ViewMixins | action |
|---|---|
| ObjectListViewMixin | list |
| ObjectDetailViewMixin | retrieve |
| ObjectEditViewMixin | create/update |
| ObjectDestroyViewMixin | destroy |
| ObjectBulkDestroyViewMixin | bulk_destroy |
| ObjectBulkCreateViewMixin | bulk_create |
| ObjectBulkUpdateViewMixin | bulk_update |
For example, for a DetailView template for YourAppModel, the template name will be yourapp/yourappmodel_retrieve.html, for a BulkCreateView template for yourappmodel, the template name will be yourapp/yourappmodel_bulk_create.html and etc.
If you do not provide your own templates in the yourapp/templates/yourapp folder, NautobotUIViewSet will fall back to generic/object_{self.action}.html.
Since in many cases the create and update templates for a model will be identical, you are not required to create both. If you provide a {app_label}/{model_opts.model_name}_create.html file but not a {app_label}/{model_opts.model_name}_update.html file, then when you update an object, it will fall back to {app_label}/{model_opts.model_name}_create.html and vice versa.