how to set custom fields from custom scripts

374 views
Skip to first unread message

maureen schaar

unread,
Dec 17, 2019, 3:28:41 AM12/17/19
to NetBox
Hi,
We are using netbox 2.6.7 with custom scripts. I am writing a script to create a VRF, but we use custom fields for this. From the api it is very simple to set the custom field values, but from script I have not found how to do this. 
Is this supported? Someone have an example?

Thanks.

Maureen

Brian Candler

unread,
Dec 17, 2019, 4:00:17 AM12/17/19
to NetBox
Custom scripts talk directly to the django ORM layer - you can use nbshell to test it out interactively.

Custom field values live in their own table and have their own model.  There is a mix-in to make them easier to use, see for example:

class VRF(ChangeLoggedModel, CustomFieldModel):

This add a "cf" property to the model, which lets you read the current custom field values.  However, I don't know of a short-cut for setting or updating custom fields. The code which does it for the API can be found here:

    def _save_custom_fields(self, instance, custom_fields):
        content_type = ContentType.objects.get_for_model(self.Meta.model)
        for field_name, value in custom_fields.items():
            custom_field = CustomField.objects.get(name=field_name)
            CustomFieldValue.objects.update_or_create(
                field=custom_field,
                obj_type=content_type,
                obj_id=instance.pk,
                defaults={'serialized_value': custom_field.serialize_value(value)},
            )

That is, it's directly creating or updating instances of CustomFieldValue.

Netbox end-users weren't originally expected to interact directly with the ORM, but this has changed with the introduction of Custom Scripts.  So it might be worth raising a feature request for an easier way to create an object with custom field values.

Regards,

Brian.

maureen schaar

unread,
Dec 17, 2019, 4:19:19 AM12/17/19
to Brian Candler, NetBox
Hi Brian,
Thanks for your reply. Yes I was able to read the customfields for the object that was created after running the script, but in order to set them, we need to find the relation that leads to the instance that created them.
Indeed, look like this was not intended for end-users.

Regards,

Maureen

--
You received this message because you are subscribed to the Google Groups "NetBox" group.
To unsubscribe from this group and stop receiving emails from it, send an email to netbox-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/netbox-discuss/f491e46b-804e-400f-bf55-20201ef5024c%40googlegroups.com.

Brian Candler

unread,
Dec 17, 2019, 4:40:36 AM12/17/19
to NetBox
The principle is simple enough: to create a VRF with two custom field values, you would first create an instance of the VRF model, and then two instances of CustomFieldValue linked to it.  More precisely: each CustomFieldValue has to link the VRF instance (via obj_type / obj_id fields) and also to the relevant CustomField (which is the *definition* of the custom field).

Sorry I don't have some sample code to show you which does exactly that, but more or less you'd copy what _save_custom_fields does.

maureen schaar

unread,
Dec 17, 2019, 8:57:46 AM12/17/19
to Brian Candler, NetBox
Hi Brian,
Perhaps this is simple for someone knowledgeable about the Django framework ;-), but I am struggling to understand how the GenericRelation is implemented in this case to link the customfields and customfieldvalues to it. 
But thanks anyway. 

Maureen

On Tue, Dec 17, 2019 at 10:40 AM Brian Candler <b.ca...@pobox.com> wrote:
The principle is simple enough: to create a VRF with two custom field values, you would first create an instance of the VRF model, and then two instances of CustomFieldValue linked to it.  More precisely: each CustomFieldValue has to link the VRF instance (via obj_type / obj_id fields) and also to the relevant CustomField (which is the *definition* of the custom field).

Sorry I don't have some sample code to show you which does exactly that, but more or less you'd copy what _save_custom_fields does.

--
You received this message because you are subscribed to the Google Groups "NetBox" group.
To unsubscribe from this group and stop receiving emails from it, send an email to netbox-discus...@googlegroups.com.

Brian Candler

unread,
Dec 17, 2019, 9:33:33 AM12/17/19
to NetBox
I have a custom field called "Warranty Type" on the "Device" model.

root@netbox:~# cd /opt/netbox/netbox/
root@netbox:/opt/netbox/netbox# python3 manage.py nbshell
### NetBox interactive shell (netbox)
### Python 3.6.9 | Django 2.2.8 | NetBox 2.6.9
### lsmodels() will show available models. Use help(<model>) for more info.
>>> from extras.models import ContentType
>>> ct = ContentType.objects.get_for_model(Device)
>>> ct
<ContentType: device>
>>> cf = CustomField.objects.get(obj_type=ct, name="Warranty Type")
>>> cf
<CustomField: Warranty type>
>>> cf.type
600

This is CF_TYPE_SELECT from netbox/extras/constants.py, so the available selections for this field are also defined in the database:

>>> CustomFieldChoice.objects.filter(field=cf)
<QuerySet [<CustomFieldChoice: Stortrec NBD>, <CustomFieldChoice: Dell Basic>, <CustomFieldChoice: Dell ProSupport>, ...
>>> ch = CustomFieldChoice.objects.get(field=cf, value="Apple Care Plus")
>>>

Finally, I want to set this on a particular device:

>>> d = Device.objects.get(name="DAS03")
>>> CustomFieldValue.objects.update_or_create(field=cf, obj_type=ct, obj_id=d.id, serialized_value=ch.id)
(<CustomFieldValue: DAS03 Warranty type>, True)
>>> 
>>> d.cf["Warranty Type"]
<CustomFieldChoice: Apple Care Plus>

If you're using text custom fields, then I think the serialized_value is just the text, which makes it simpler.

maureen schaar

unread,
Dec 18, 2019, 7:54:08 AM12/18/19
to Brian Candler, NetBox
hi Brian,
Thanks a lot! It now works for me thanks to your example.
Very happy with prompt responses! 

Maureen

--
You received this message because you are subscribed to the Google Groups "NetBox" group.
To unsubscribe from this group and stop receiving emails from it, send an email to netbox-discus...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages