Remove slugs from all models #5759

Closed
opened 2025-12-29 19:32:15 +01:00 by adam · 24 comments
Owner

Originally created by @jeremystretch on GitHub (Dec 10, 2021).

Proposed Changes

Remove the slug field from all models which have one. Any filters which reference the slug field will be modified to reference the object's name instead.

Justification

Slugs were phased out of use in URLs under #6097 and no longer serve any real purpose. NetBox users who utilize this field to store data should switch to using a custom field.

Originally created by @jeremystretch on GitHub (Dec 10, 2021). ### Proposed Changes Remove the `slug` field from all models which have one. Any filters which reference the slug field will be modified to reference the object's name instead. ### Justification Slugs were phased out of use in URLs under #6097 and no longer serve any real purpose. NetBox users who utilize this field to store data should switch to using a custom field.
adam added the type: deprecation label 2025-12-29 19:32:15 +01:00
adam closed this issue 2025-12-29 19:32:16 +01:00
Author
Owner

@DanSheps commented on GitHub (Dec 10, 2021):

I would have to double check, but I do believe we use slugs in a few filters as a way to query (?role=xxx vs ?role_id=###)

This might be impactful for API reasons and we might want to look at that more carefully.

@DanSheps commented on GitHub (Dec 10, 2021): I would have to double check, but I do believe we use slugs in a few filters as a way to query (?role=xxx vs ?role_id=###) This might be impactful for API reasons and we might want to look at that more carefully.
Author
Owner

@DanSheps commented on GitHub (Dec 10, 2021):

Thinking about this more...

I would have to vote against this. The recommendation for switching to custom fields, I feel, is too burdensome on the user. Custom fields aren't a "hard" field with specific requirements:

  1. Requires "maintenance" of the slug custom field (if someone deletes it accidentally that could be disasterous)
  2. There is no uniqueness constraint on a individual custom field. Two devices could potentially have the cf_slug "test" (Might be able to work around this with custom validators but that does add a extra burden on someone and I haven't even checked to see if this is possible).
  3. Requires an additional REST API or Python API query (/api/ipam/prefixes/?tenant=dunder-mifflin vs /api/tenancy/tenant/?q=Dunder%20Mifflin and /api/ipam/prefixes/?tenant_id=#)
  4. More prone to errors with lookups (tenant=dunder-mifflin vs where you have to perform a lookup for # first by searching against Dunder Mifflin in the tenant API, then fetch the data you need) Incorrect punctuation or a typo could result in incorrect or no data returned. This could happen with a slug field, however slug fields have certain restrictions that make this less likely (no whitespace, alphanum and -_ etc)
  5. Python API, you cannot access the custom field in the same way as a slug (site__slug)
  6. This would require manual migration of all slugs to PK's by those who utilize them. Also requires upgrading whatever integrations are in use to query against the custom field instead of the slug.

If some of these are addressable, maybe we mark this as blocked until we can implement those workarounds?

@DanSheps commented on GitHub (Dec 10, 2021): Thinking about this more... I would have to vote against this. The recommendation for switching to custom fields, I feel, is too burdensome on the user. Custom fields aren't a "hard" field with specific requirements: 1. Requires "maintenance" of the slug custom field (if someone deletes it accidentally that could be disasterous) 2. There is no uniqueness constraint on a individual custom field. Two devices could potentially have the cf_slug "test" (Might be able to work around this with custom validators but that does add a extra burden on someone and I haven't even checked to see if this is possible). 3. Requires an additional REST API or Python API query (/api/ipam/prefixes/?tenant=dunder-mifflin vs /api/tenancy/tenant/?q=Dunder%20Mifflin and /api/ipam/prefixes/?tenant_id=#) 4. More prone to errors with lookups (tenant=dunder-mifflin vs where you have to perform a lookup for # first by searching against Dunder Mifflin in the tenant API, then fetch the data you need) Incorrect punctuation or a typo could result in incorrect or no data returned. This could happen with a slug field, however slug fields have certain restrictions that make this less likely (no whitespace, alphanum and -_ etc) 5. Python API, you cannot access the custom field in the same way as a slug (site__slug) 6. This would require manual migration of all slugs to PK's by those who utilize them. Also requires upgrading whatever integrations are in use to query against the custom field instead of the slug. If some of these are addressable, maybe we mark this as blocked until we can implement those workarounds?
Author
Owner

@rodvand commented on GitHub (Dec 10, 2021):

I know the ansible modules heavily uses slugs for its functionality. So removing them would require a rework on the modules.

@rodvand commented on GitHub (Dec 10, 2021): I know the ansible modules heavily uses slugs for its functionality. So removing them would require a rework on the modules.
Author
Owner

@jeremystretch commented on GitHub (Dec 10, 2021):

  1. Requires "maintenance" of the slug custom field

Does it? Only if you have a specific need to store a slug for an object in the first place, which I would guess most users do not.

  1. There is no uniqueness constraint on a individual custom field.

As slugs are no longer used in URLs, there's really no need for them to be unique (or to exist at all).

  1. Requires an additional REST API or Python API query

This is true for slugs as well: You can't assume that a slug is known ahead of time. You might be able to guess it 99% of the time, but that's not good enough to avoid querying entirely.

  1. More prone to errors with lookups

Same as above. The argument is predicated on knowing the slug ahead of time, which is not reasonable.

  1. Python API, you cannot access the custom field in the same way as a slug (site__slug)

You would access it as site__custom_field_data__slug. I don't see a significant distinction.

  1. This would require manual migration of all slugs to PK's by those who utilize them.

Sure, and I think that's a reasonable one-time request to ditch a significant amount of unnecessary overhead. On the flip side, users who don't need slugs will never again be forced to populate them when creating objects.

I know the ansible modules heavily uses slugs for its functionality. So removing them would require a rework on the modules.

It's worth pointing out that only 21 or around 80 models currently have a slug field. So, presumably, we can simply standardize on those what we do for the others. Ultimately this should reduce code and make the library easier to maintain in general.

@jeremystretch commented on GitHub (Dec 10, 2021): > 1. Requires "maintenance" of the slug custom field Does it? Only if you have a specific need to store a slug for an object in the first place, which I would guess most users do not. > 2. There is no uniqueness constraint on a individual custom field. As slugs are no longer used in URLs, there's really no need for them to be unique (or to exist at all). > 3. Requires an additional REST API or Python API query This is true for slugs as well: You can't assume that a slug is known ahead of time. You might be able to guess it 99% of the time, but that's not good enough to avoid querying entirely. > 4. More prone to errors with lookups Same as above. The argument is predicated on knowing the slug ahead of time, which is not reasonable. > 5. Python API, you cannot access the custom field in the same way as a slug (site__slug) You would access it as `site__custom_field_data__slug`. I don't see a significant distinction. > 6. This would require manual migration of all slugs to PK's by those who utilize them. Sure, and I think that's a reasonable one-time request to ditch a significant amount of unnecessary overhead. On the flip side, users who _don't_ need slugs will never again be forced to populate them when creating objects. > I know the ansible modules heavily uses slugs for its functionality. So removing them would require a rework on the modules. It's worth pointing out that only 21 or around 80 models currently have a slug field. So, presumably, we can simply standardize on those what we do for the others. Ultimately this should reduce code and make the library easier to maintain in general.
Author
Owner

@kkthxbye-code commented on GitHub (Dec 10, 2021):

I'm voting for. Slugs are for URL's, and if they are not used for URL's anymore, remove them.

If you know what object you want without lookup, just use the id.

@kkthxbye-code commented on GitHub (Dec 10, 2021): I'm voting for. Slugs are for URL's, and if they are not used for URL's anymore, remove them. If you know what object you want without lookup, just use the id.
Author
Owner

@DanSheps commented on GitHub (Dec 11, 2021):

Slugs are for URL's, and if they are not used for URL's anymore, remove them.

Technically not correct, a slug is a URL friendly label:

Source

Slug is a newspaper term. A slug is a short label for something, containing only letters, numbers, underscores or hyphens. They’re generally used in URLs.

We use them in URLs but that isn't all they are.

If you know what object you want without lookup, just use the id.

ID's are not always fixed, generally slugs are.

@DanSheps commented on GitHub (Dec 11, 2021): > Slugs are for URL's, and if they are not used for URL's anymore, remove them. Technically not correct, a slug is a *URL friendly* label: [Source](https://docs.djangoproject.com/en/4.0/ref/models/fields/#slugfield) > Slug is a newspaper term. A slug is a short label for something, containing only letters, numbers, underscores or hyphens. They’re generally used in URLs. We use them in URLs but that isn't all they are. > If you know what object you want without lookup, just use the id. ID's are not always fixed, generally slugs are.
Author
Owner

@kkthxbye-code commented on GitHub (Dec 11, 2021):

We use them in URLs but that isn't all they are.

I'm not going engage in an argument based on the etymology of a word. How we use slugs in netbox should be all that matters.

https://en.wikipedia.org/wiki/Clean_URL#Slug

ID's are not always fixed, generally slugs are.

How can you change a pk in netbox from the UI or API without creating a new object? Are there any instances where you could see a valid reason to change the pk of an object? Essentially pk's are more static than slugs, because slugs can be changed at will.

@kkthxbye-code commented on GitHub (Dec 11, 2021): >We use them in URLs but that isn't all they are. I'm not going engage in an argument based on the etymology of a word. How we use slugs in netbox should be all that matters. https://en.wikipedia.org/wiki/Clean_URL#Slug >ID's are not always fixed, generally slugs are. How can you change a pk in netbox from the UI or API without creating a new object? Are there any instances where you could see a valid reason to change the pk of an object? Essentially pk's are more static than slugs, because slugs can be changed at will.
Author
Owner

@jeremystretch commented on GitHub (Dec 11, 2021):

There's a compromise approach as well: We can just make slugs optional fields for now. This will at least alleviate the burden of having to define slugs that are otherwise unused, without interfering with those that are. I'd still like to eventually remove slugs completely, but this can happen at a later point in the future.

@jeremystretch commented on GitHub (Dec 11, 2021): There's a compromise approach as well: We can just make slugs optional fields for now. This will at least alleviate the burden of having to define slugs that are otherwise unused, without interfering with those that are. I'd still like to eventually remove slugs completely, but this can happen at a later point in the future.
Author
Owner

@sol1-matt commented on GitHub (Dec 11, 2021):

I am voting against. I think removing slugs from Netbox is a bad idea. The reasons for this are

  • the slug field is created automatically
  • the slug field is a predictable computer friendly reference to the object that isn't a number.
  • the slug value is enforced to be unique in a way that name isn't, it doesn't allow duplicates at the source
  • the slug field has historically been a human readable reference between many objects in Netbox and any systems that use Netbox as a source or truth likely have a technical debt to them

Slugs are incredibly useful in any sort of automation compared with name or id. The types of automation I've had experience with are monitoring (Icinga), Ansible and other custom glue scripts that exchange data between Netbox and other sources.

Because slugs are automatically generated it makes it less likely humans will do something to break linked systems they don't know or care about, automatic slug creation does the work for them. Not having the slug created automatically at data entry time means the user needs to perform work previously done automatically and in the case of using a custom field as a replacement the linked object no longer shares the same value.

Having a automatically generated computer friendly, default /[a-z]-_/, unique value as a reference in the source or truth makes using that data in other systems easy to do. Being able to reference a site by slug, eg example or site_example, is has benefits over id, 123 or site_123. Both Icinga and Ansible benefit from slugs, Icinga because monitoring object names that contain the slug over id are instantly recognisable to the humans who manage monitoring, Ansible for the same reason as group names that use the slugs are referenced in playbooks so - host: site_example is much more readable than - host: site_123

The name of an object isn't a adequate replacement for slug, names are case sensitive and can have a much wider range of characters. The slug creation in Netbox simplifies the name (automatically) but will alert the user to problems only if found. It is particularly good a picking up objects with the same name but different case. There are 2 benefits to this a) Netbox is less likely to have bad or confusing data like the same server entered twice or assigned the same name and b) external system can trust the uniqueness of Netbox data.

Currently slugs are used as a reference between objects and are useful over id's. If in external systems we want to reference a devices site the slug between the 2 can be used. Monitoring and automation systems tend to be configuration based, not code based and as such humans will want to read the configuration, import site_example is easier to understand than import site_123

External systems replicating slugs on the way in
There are individual problems with this but the main effect is Netbox data is less truthful. Some of the individual problems introduced because Netbox no longer has slugs is

External slug creation errors due to duplicates or other human error gets moved from data entry time to export time.

External systems that import Netbox objects independently, ie 1 object type only, will only have the id as a link as the name part only exists on one side so a slug can only be created on one side, not both unless they are imported already linked.

External systems that import only one object type at a time that load linked objects to recreate slugs dramatically increase load, 2500 devices = 3 api calls now vs 3 api call + 2500 api calls per linked object or just load everything from all linked objects.

External systems that read data from Netbox and then later use that data to enhance data in Netbox will need to store Netbox specific references for the object that are seperate from the externally generated slug replacement because Netbox will no longer have any idea on what the object is.

@sol1-matt commented on GitHub (Dec 11, 2021): I am voting against. I think removing slugs from Netbox is a bad idea. The reasons for this are - the slug field is created automatically - the slug field is a predictable computer friendly reference to the object that isn't a number. - the slug value is enforced to be unique in a way that name isn't, it doesn't allow duplicates at the source - the slug field has historically been a human readable reference between many objects in Netbox and any systems that use Netbox as a source or truth likely have a technical debt to them Slugs are incredibly useful in any sort of automation compared with `name` or `id`. The types of automation I've had experience with are monitoring ([Icinga](https://github.com/sol1/icingaweb2-module-netbox)), Ansible and other custom glue scripts that exchange data between Netbox and other sources. Because slugs are automatically generated it makes it less likely humans will do something to break linked systems they don't know or care about, automatic slug creation does the work for them. Not having the slug created automatically at data entry time means the user needs to perform work previously done automatically and in the case of using a custom field as a replacement **the linked object no longer shares the same value.** Having a automatically generated computer friendly, default `/[a-z]-_/`, unique value as a reference in the source or truth makes using that data in other systems easy to do. Being able to reference a site by slug, eg `example` or `site_example`, is has benefits over id, `123` or `site_123`. Both Icinga and Ansible benefit from slugs, Icinga because monitoring object names that contain the slug over id are instantly recognisable to the humans who manage monitoring, Ansible for the same reason as group names that use the slugs are referenced in playbooks so ` - host: site_example` is much more readable than ` - host: site_123` The name of an object isn't a adequate replacement for slug, names are case sensitive and can have a much wider range of characters. The slug creation in Netbox simplifies the name (automatically) but will alert the user to problems only if found. It is particularly good a picking up objects with the same name but different case. There are 2 benefits to this a) Netbox is less likely to have bad or confusing data like the same server entered twice or assigned the same name and b) external system can trust the uniqueness of Netbox data. Currently slugs are used as a reference between objects and are useful over id's. If in external systems we want to reference a devices site the slug between the 2 can be used. Monitoring and automation systems tend to be configuration based, not code based and as such humans will want to read the configuration, `import site_example` is easier to understand than `import site_123` **External systems replicating slugs on the way in** There are individual problems with this but the main effect is Netbox data is less truthful. Some of the individual problems introduced because Netbox no longer has slugs is External slug creation errors due to duplicates or other human error gets moved from data entry time to export time. External systems that import Netbox objects independently, ie 1 object type only, will only have the `id` as a link as the `name` part only exists on one side so a slug can only be created on one side, not both unless they are imported already linked. External systems that import only one object type at a time that load linked objects to recreate slugs dramatically increase load, 2500 devices = 3 api calls now vs 3 api call + 2500 api calls per linked object or just load everything from all linked objects. External systems that read data from Netbox and then later use that data to enhance data in Netbox will need to store Netbox specific references for the object that are seperate from the externally generated slug replacement because Netbox will no longer have any idea on what the object is.
Author
Owner

@sol1-matt commented on GitHub (Dec 11, 2021):

There's a compromise approach as well: We can just make slugs optional fields for now. This will at least alleviate the burden of having to define slugs that are otherwise unused, without interfering with those that are. I'd still like to eventually remove slugs completely, but this can happen at a later point in the future.

Optional as in a setting that is REQUIRE_SLUGS = TRUE or optional as in doesn't need to be filled out?

If it doesn't need to be filled out is it still filled out automatically?

Edit: Could we get some more examples of the problems slugs create, perhaps there is a different solution rather than removing slugs all together.

@sol1-matt commented on GitHub (Dec 11, 2021): > There's a compromise approach as well: We can just make slugs optional fields for now. This will at least alleviate the burden of having to define slugs that are otherwise unused, without interfering with those that are. I'd still like to eventually remove slugs completely, but this can happen at a later point in the future. Optional as in a setting that is `REQUIRE_SLUGS = TRUE` or optional as in doesn't need to be filled out? If it doesn't need to be filled out is it still filled out automatically? Edit: Could we get some more examples of the problems slugs create, perhaps there is a different solution rather than removing slugs all together.
Author
Owner

@jeremystretch commented on GitHub (Dec 11, 2021):

the slug field is created automatically

Only when creating objects via the UI. There is no automation when using the REST API.

the slug field is a predictable computer friendly reference to the object that isn't a number.

As would be a custom field that replaces it.

the slug value is enforced to be unique in a way that name isn't, it doesn't allow duplicates at the source

I can't think of any instances where this is true. Uniqueness is enforced for both name and slug consistently for each model. They are redundant.

the slug field has historically been a human readable reference between many objects in Netbox and any systems that use Netbox as a source or truth likely have a technical debt to them

There are no inter-object relationships in NetBox which depend on the slug field. It was only ever used in URLs (gone in v2.11) and filter sets.

@jeremystretch commented on GitHub (Dec 11, 2021): > the slug field is created automatically Only when creating objects via the UI. There is no automation when using the REST API. > the slug field is a predictable computer friendly reference to the object that isn't a number. As would be a custom field that replaces it. > the slug value is enforced to be unique in a way that name isn't, it doesn't allow duplicates at the source I can't think of any instances where this is true. Uniqueness is enforced for both name and slug consistently for each model. They are redundant. > the slug field has historically been a human readable reference between many objects in Netbox and any systems that use Netbox as a source or truth likely have a technical debt to them There are no inter-object relationships in NetBox which depend on the slug field. It was only ever used in URLs (gone in v2.11) and filter sets.
Author
Owner

@sol1-matt commented on GitHub (Dec 11, 2021):

Only when creating objects via the UI. There is no automation when using the REST API.

This is true, but I trust developers more than I trust users and it is generally easier to find the developers and tell them to change the code than retrain users

As would be a custom field that replaces it.

the custom field only exists on one side of a object, a site slug custom field would only exist on the site, the device wouldn't have any idea of what the site slug custom field is from itself it needs the id for that and if you are loading the whole site but using the site stub on the device object there is a problem

{
    "id": 99,
    "url": "https://demo.netbox.dev/api/dcim/devices/99/",
    "display": "FW001",
    "name": "FW001",
    ....
    "site": {
        "id": 21,
        "url": "https://demo.netbox.dev/api/dcim/sites/21/",
        "display": "MDF",
        "name": "MDF",
        "slug": "ncsu-065"
    },
    ...

I can't think of any instances where this is true. Uniqueness is enforced for both name and slug consistently for each model. They are redundant.

Case is the big one for uniqueness, slug is good at telling the user when they have been dumb and entered a duplicate with different case aka FooBar and Foobar. Some external systems are case insensitive and slug is a lifesaver when it comes to using Netbox as a source of truth for them.

There are no inter-object relationships in NetBox which depend on the slug field. It was only ever used in URLs (gone in v2.11) and filter sets.

I agree with that, but I wasn't referencing Netbox but other systems that use Netbox as a source of truth that recreate objects in their own way. Netbox's model approach translates well so it get replicated :)

Thinking about this more the benefits slugs give external applications might be resolved by allowing rules to be set around name. That way the cost of slugs could be removed but the benefits (a trusted field users can't screw up) could be retained, win-win.

@sol1-matt commented on GitHub (Dec 11, 2021): > Only when creating objects via the UI. There is no automation when using the REST API. This is true, but I trust developers more than I trust users and it is generally easier to find the developers and tell them to change the code than retrain users > As would be a custom field that replaces it. the custom field only exists on one side of a object, a site slug custom field would only exist on the site, the device wouldn't have any idea of what the site slug custom field is from itself it needs the id for that and if you are loading the whole site but using the site stub on the device object there is a problem ``` { "id": 99, "url": "https://demo.netbox.dev/api/dcim/devices/99/", "display": "FW001", "name": "FW001", .... "site": { "id": 21, "url": "https://demo.netbox.dev/api/dcim/sites/21/", "display": "MDF", "name": "MDF", "slug": "ncsu-065" }, ... ``` >I can't think of any instances where this is true. Uniqueness is enforced for both name and slug consistently for each model. They are redundant. Case is the big one for uniqueness, slug is good at telling the user when they have been dumb and entered a duplicate with different case aka FooBar and Foobar. Some external systems are case insensitive and slug is a lifesaver when it comes to using Netbox as a source of truth for them. > There are no inter-object relationships in NetBox which depend on the slug field. It was only ever used in URLs (gone in v2.11) and filter sets. I agree with that, but I wasn't referencing Netbox but other systems that use Netbox as a source of truth that recreate objects in their own way. Netbox's model approach translates well so it get replicated :) Thinking about this more the benefits slugs give external applications might be resolved by allowing rules to be set around `name`. That way the cost of slugs could be removed but the benefits (a trusted field users can't screw up) could be retained, win-win.
Author
Owner

@sol1-matt commented on GitHub (Dec 11, 2021):

19 minutes worth of though so this might be brilliant or terrible.

A number of the benefits of slug that make Netbox useful as a source of truth to external applications exists with the name field.

Being able to configure the name field to allow administrators to configure what can be entered (case insensitive unique, starts with a S, no vowels, etc...) would make the name field a good replacement for slug when needed.

Allowing multiple rule sets that could be applied at both the object level and objects role/group level would help prevent the problems that currently exist with slug being migrated to name.

@sol1-matt commented on GitHub (Dec 11, 2021): 19 minutes worth of though so this might be brilliant or terrible. A number of the benefits of `slug` that make Netbox useful as a source of truth to external applications exists with the `name` field. Being able to configure the `name` field to allow administrators to configure what can be entered (case insensitive unique, starts with a S, no vowels, etc...) would make the `name` field a good replacement for slug when needed. Allowing multiple rule sets that could be applied at both the object level and objects role/group level would help prevent the problems that currently exist with `slug` being migrated to `name`.
Author
Owner

@kkthxbye-code commented on GitHub (Dec 11, 2021):

Case is the big one for uniqueness, slug is good at telling the user when they have been dumb and entered a duplicate with different case aka FooBar and Foobar. Some external systems are case insensitive and slug is a lifesaver when it comes to using Netbox as a source of truth for them.

Slug uniqueness is case sensitive afaik, so that's not even true.

image

@kkthxbye-code commented on GitHub (Dec 11, 2021): > Case is the big one for uniqueness, **slug is good at telling the user when they have been dumb and entered a duplicate with different case aka FooBar and Foobar**. Some external systems are case insensitive and slug is a lifesaver when it comes to using Netbox as a source of truth for them. Slug uniqueness is case sensitive afaik, so that's not even true. ![image](https://user-images.githubusercontent.com/400797/145661739-3cb5c495-8013-490c-a33f-712fd0e6ee35.png)
Author
Owner

@DanSheps commented on GitHub (Dec 11, 2021):

How can you change a pk in netbox from the UI or API without creating a new object? Are there any instances where you could see a valid reason to change the pk of an object? Essentially pk's are more static than slugs, because slugs can be changed at will.

Certain transactions can cause PK's to change. Certain types of replication could cause PK's to change.

A slug defined by you will always be the same unless it is changed by you.

Case is the big one for uniqueness, slug is good at telling the user when they have been dumb and entered a duplicate with different case aka FooBar and Foobar. Some external systems are case insensitive and slug is a lifesaver when it comes to using Netbox as a source of truth for them.

This is only sort of true. It is true if you accept the default auto-generated slug. Not so true if you edit the slug after it is auto-generated.

I think perhaps having slug optional would be the way to go. Maybe even adding the ability to turn off display of slug in the configuration might be best.

@DanSheps commented on GitHub (Dec 11, 2021): > How can you change a pk in netbox from the UI or API without creating a new object? Are there any instances where you could see a valid reason to change the pk of an object? Essentially pk's are more static than slugs, because slugs can be changed at will. Certain transactions can cause PK's to change. Certain types of replication could cause PK's to change. A slug defined by you will always be the same unless it is changed by you. > Case is the big one for uniqueness, slug is good at telling the user when they have been dumb and entered a duplicate with different case aka FooBar and Foobar. Some external systems are case insensitive and slug is a lifesaver when it comes to using Netbox as a source of truth for them. This is only sort of true. It is true if you accept the default auto-generated slug. Not so true if you edit the slug after it is auto-generated. I think perhaps having slug optional would be the way to go. Maybe even adding the ability to turn off display of slug in the configuration might be best.
Author
Owner

@kkthxbye-code commented on GitHub (Dec 11, 2021):

Certain transactions can cause PK's to change.

On models with slugs? Do you have an example?

A slug defined by you will always be the same unless it is changed by you.

As opposed to the name?

Certain types of replication could cause PK's to change.

Like replicating the database somewhere else and changing the pk's when doing it? If so, how is that relevant?

@kkthxbye-code commented on GitHub (Dec 11, 2021): > Certain transactions can cause PK's to change. On models with slugs? Do you have an example? > A slug defined by you will always be the same unless it is changed by you. As opposed to the name? > Certain types of replication could cause PK's to change. Like replicating the database somewhere else and changing the pk's when doing it? If so, how is that relevant?
Author
Owner

@sol1-matt commented on GitHub (Dec 11, 2021):

Slug uniqueness is case sensitive afaik, so that's not even true.

@kkthxbye-code Automatic slug creation is lowercase , the user can go out of their way to change the slug but it does tell you when you create a duplicate name with different case initially.

image

From https://demo.netbox.dev/

@sol1-matt commented on GitHub (Dec 11, 2021): > Slug uniqueness is case sensitive afaik, so that's not even true. @kkthxbye-code Automatic slug creation is lowercase , the user can go out of their way to change the slug but it does tell you when you create a duplicate name with different case initially. ![image](https://user-images.githubusercontent.com/17868735/145662888-93c0ae5a-b463-4421-bf37-793b905fdeab.png) From https://demo.netbox.dev/
Author
Owner

@sol1-matt commented on GitHub (Dec 11, 2021):

@jeremystretch has just pointed out custom validators.

I'm going to try and replace the functionality existing with slug with custom validators and name for external applications using Netbox as a source of truth next week.

@sol1-matt commented on GitHub (Dec 11, 2021): @jeremystretch has just pointed out [custom validators](https://netbox.readthedocs.io/en/stable/customization/custom-validation/). I'm going to try and replace the functionality existing with slug with custom validators and name for external applications using Netbox as a source of truth next week.
Author
Owner

@sol1-matt commented on GitHub (Dec 14, 2021):

TL;DR Can custom validators be used to ensure the name field is a suitable replacement for slug's in external applications? yes

I've done some testing of custom validators to see if the functionality of the slug for external applications can be duplicated with the name field. I think it is possible with validators.

This is an example of a validator I created

class DeviceValidator(CustomValidator):

    def validate(self, instance):
        fail_message = []
        # Exclude bits of plastic we want to document but don't interact with
        if instance.device_role not in ['Patch panel']:
            # Name format
            if not re.match('^[a-z0-9_\-. ]*$', instance.name):
                fail_message.append("must match regex '^[a-z0-9_\-. ]*$'")
            # Duplicates
            for device in Device.objects.all():
                if instance.name.lower() in device.name.lower():
                    fail_message.append("duplicate name detected '{}'".format(device.name))
        # Length
        if len(instance.name) < 5:
            fail_message.append("must be 6 or more characters long")
        if fail_message:
           self.fail("'name' field {}".format(" and ".join(fail_message)), field='name')

What does this buy me

  • I can control validation at the device role level which is good as users will complain if they need to come up with good names for bits of plastic
  • users can't add in characters I don't want them to so external application don't need to manage them, fixes occur at data entry time
  • I can ensure case insensitive duplicates don't exist, fixes occur at data entry time
  • control length, fixes occur at data entry time
  • as this is all on the name field it exists on the parent object and linked object with exactly the same value/format which is useful for externally joining object without using the id

External applications that use Netbox as a source of truth may want to slugify the name for it's own purposes, eg: ansible groups should be '^[a-z0-9_]*$'. But custom validators allow Netbox and the Netbox user to ensure the data at entry time can match pretty much any rules you can think of.

@sol1-matt commented on GitHub (Dec 14, 2021): TL;DR Can custom validators be used to ensure the name field is a suitable replacement for slug's in external applications? **yes** I've done some testing of custom validators to see if the functionality of the slug for external applications can be duplicated with the name field. I think it is possible with validators. This is an example of a validator I created ``` class DeviceValidator(CustomValidator): def validate(self, instance): fail_message = [] # Exclude bits of plastic we want to document but don't interact with if instance.device_role not in ['Patch panel']: # Name format if not re.match('^[a-z0-9_\-. ]*$', instance.name): fail_message.append("must match regex '^[a-z0-9_\-. ]*$'") # Duplicates for device in Device.objects.all(): if instance.name.lower() in device.name.lower(): fail_message.append("duplicate name detected '{}'".format(device.name)) # Length if len(instance.name) < 5: fail_message.append("must be 6 or more characters long") if fail_message: self.fail("'name' field {}".format(" and ".join(fail_message)), field='name') ``` What does this buy me * I can control validation at the device role level which is good as users will complain if they need to come up with good names for bits of plastic * users can't add in characters I don't want them to so external application don't need to manage them, fixes occur at data entry time * I can ensure case insensitive duplicates don't exist, fixes occur at data entry time * control length, fixes occur at data entry time * as this is all on the name field it exists on the parent object and linked object with exactly the same value/format which is useful for externally joining object without using the id External applications that use Netbox as a source of truth may want to slugify the name for it's own purposes, eg: ansible groups should be '^[a-z0-9_]*$'. But custom validators allow Netbox and the Netbox user to ensure the data at entry time can match pretty much any rules you can think of.
Author
Owner

@DanSheps commented on GitHub (Dec 15, 2021):

While this works for the name field, it doesn't address the fact that you might want your name field to be different then the slug. I am sure you can custom validate on slugs to, however I think a more measured approach would be to instead make the slug field optional as Jeremy mentioned. That solves both problems. If we truely want to disable the slug field, also hiding it with a config variable might be an option.

ETA: I think we would need more data to determine how slugs are being used before we consider removing them completely. We can probably put a few questions in the user survey regarding slugs.

@DanSheps commented on GitHub (Dec 15, 2021): While this works for the name field, it doesn't address the fact that you might want your name field to be different then the slug. I am sure you can custom validate on slugs to, however I think a more measured approach would be to instead make the slug field optional as Jeremy mentioned. That solves both problems. If we truely want to disable the slug field, also hiding it with a config variable might be an option. ETA: I think we would need more data to determine how slugs are being used before we consider removing them completely. We can probably put a few questions in the user survey regarding slugs.
Author
Owner

@sol1-matt commented on GitHub (Dec 16, 2021):

While this works for the name field, it doesn't address the fact that you might want your name field to be different then the slug. I am sure you can custom validate on slugs to, however I think a more measured approach would be to instead make the slug field optional as Jeremy mentioned. That solves both problems. If we truely want to disable the slug field, also hiding it with a config variable might be an option.

You can make the name a slug for external applications, or at least create a safe slug from the name. The validator can be abused quite nicely to ensure users can't enter the wrong thing either.

The slug field currently has a couple of features that are useful

  • required
  • automatic
  • exists on original and linked objects
  • quasi safe in the it defaults to lowercase do case duplicates are found

If the slug field becomes optional what is the behavior for ON?
For instance if an optional slug doesn't appear on linked objects the usefulness drops dramatically for some external applications.

This is why I'm suggesting the name field with validation is a slug replacement for those that need it (such as myself). With custom validation name can be made better than current slugs.

@sol1-matt commented on GitHub (Dec 16, 2021): > While this works for the name field, it doesn't address the fact that you might want your name field to be different then the slug. I am sure you can custom validate on slugs to, however I think a more measured approach would be to instead make the slug field optional as Jeremy mentioned. That solves both problems. If we truely want to disable the slug field, also hiding it with a config variable might be an option. You can make the `name` a `slug` for external applications, or at least create a safe `slug` from the `name`. The [validator can be abused quite nicely](https://github.com/netbox-community/netbox/issues/8058#issuecomment-994130668) to ensure users can't enter the wrong thing either. The slug field currently has a couple of features that are useful * required * automatic * exists on original and linked objects * quasi safe in the it defaults to lowercase do case duplicates are found If the slug field becomes optional what is the behavior for ON? For instance if an optional slug doesn't appear on linked objects the usefulness drops dramatically for some external applications. This is why I'm suggesting the `name` field with validation is a slug replacement for those that need it (such as myself). With custom validation `name` can be made better than current slugs.
Author
Owner

@DanSheps commented on GitHub (Dec 17, 2021):

By validating on name, you are decreasing the usefulness of the name field though, and you may have instances where the name needs the character that isn't available in the slug character limit

@DanSheps commented on GitHub (Dec 17, 2021): By validating on name, you are decreasing the usefulness of the name field though, and you may have instances where the name needs the character that isn't available in the slug character limit
Author
Owner

@candlerb commented on GitHub (Dec 18, 2021):

I'd like to make a completely off-field counter-proposal, which I'll call "embrace the slug". The principles are:

  1. All models have slugs[^1]
  2. The slug is a mandatory field and is unique across all objects of that type[^2], enforced by DB unique index
  3. If you don't assign a slug[^3] then it gets a GUID
  4. The slug should not change after object creation[^4]

At this point the slug is just another ID, like the sequential numeric ID. The big difference is that it can be understood across systems.

This form of ID allows some things which are not possible today:

  • idempotent "UPSERT" operations. When creating new objects, a GUID slug can be chosen client-side (you know it will be unique). If the slug exists then update the existing record; else create a new record
  • selective sync or replication of objects between different Netbox systems (export with slug, import/upsert with slug)

And there are some things which would be possible today with numeric IDs, but which work better with slugs:

  • bulk update via CSV upload (#7961). This could be done using IDs, but slugs would decouple from the internal details of a particular database instance
  • more easily reference and update things which may have no name, or where the name may not be unique (e.g. devices)

[^1] The only exception might be things which have mandatory and globally unique names, e.g. tags.

[^2] This also allows globally unique references to be formed, as <object-type>:<slug>. Essentially this is how Salesforce object IDs work.

[^3] Slugs are most powerful when GUIDs, and lose their inter-system uniqueness properties if selected manually. When creating objects via the web UI, you could allow the user to select a slug, or even pick a default as today, e.g. based on the name, plus a suffix if it already exists. However, I'm leaning towards making slugs be GUIDs always.

[^4] Not necessarily impossible, but it should be discouraged, and hard to do by default. In particular, the "edit" page for an object should leave the slug field non-editable by default. If slugs are GUIDs then there should be no reason at all to change them.

@candlerb commented on GitHub (Dec 18, 2021): I'd like to make a completely off-field counter-proposal, which I'll call "embrace the slug". The principles are: 1. *All* models have slugs[^1] 2. The slug is a mandatory field and is unique across all objects of that type[^2], enforced by DB unique index 3. If you don't assign a slug[^3] then it gets a GUID 4. The slug should not change after object creation[^4] At this point the slug is just another ID, like the sequential numeric ID. The big difference is that it can be understood across systems. This form of ID allows some things which are not possible today: - idempotent "UPSERT" operations. When creating new objects, a GUID slug can be chosen client-side (you know it will be unique). If the slug exists then update the existing record; else create a new record - selective sync or replication of objects between different Netbox systems (export with slug, import/upsert with slug) And there are some things which would be possible today with numeric IDs, but which work better with slugs: - bulk update via CSV upload (#7961). This could be done using IDs, but slugs would decouple from the internal details of a particular database instance - more easily reference and update things which may have no name, or where the name may not be unique (e.g. devices) ----- [^1] The only exception *might* be things which have mandatory and globally unique names, e.g. tags. [^2] This also allows globally unique references to be formed, as `<object-type>:<slug>`. Essentially this is how Salesforce object IDs work. [^3] Slugs are most powerful when GUIDs, and lose their inter-system uniqueness properties if selected manually. When creating objects via the web UI, you *could* allow the user to select a slug, or even pick a default as today, e.g. based on the name, plus a suffix if it already exists. However, I'm leaning towards making slugs be GUIDs always. [^4] Not necessarily impossible, but it should be discouraged, and hard to do by default. In particular, the "edit" page for an object should leave the slug field non-editable by default. If slugs are GUIDs then there should be no reason at all to change them.
Author
Owner

@jeremystretch commented on GitHub (Dec 19, 2021):

I don't think this is worth discussing any further. Although I disagree with all the counterpoints raised in favor of retaining slugs, there's clearly a substantial amount of dissent, so we're not going to remove them completely at this time.

As a potential compromise between those users who rely on slugs and those who perceive them as a burden, I've proposed in #8113 that we alter all slug fields to no longer be required fields. Users are encourage to provide feedback. Hopefully this proposal will prove to be less contentious.

@jeremystretch commented on GitHub (Dec 19, 2021): I don't think this is worth discussing any further. Although I disagree with all the counterpoints raised in favor of retaining slugs, there's clearly a substantial amount of dissent, so we're not going to remove them completely at this time. As a potential compromise between those users who rely on slugs and those who perceive them as a burden, I've proposed in #8113 that we alter all slug fields to no longer be required fields. Users are encourage to provide feedback. Hopefully this proposal will prove to be less contentious.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#5759