netbox: Non-ascii tag creates empty slug, exception django.urls.exceptions.NoReverseMatch

Environment

  • Python version: 3.5.2
  • NetBox version: 2.6.7

Steps to Reproduce

  1. edit a device
  2. add a tag consisting soley of non-ASCII characters, e.g. 台灣
  3. save
  4. go to Organization > Tags (/extras/tags/) in the GUI

Expected Behavior

Tag to be functional

Observed Behavior

I get an exception:

<class 'django.urls.exceptions.NoReverseMatch'>

Reverse for 'tag' with arguments '('',)' not found. 1 pattern(s) tried: ['extras\\/tags\\/(?P<slug>[-a-zA-Z0-9_]+)\\/$']

If I query the database, I find that a tag has been created with an empty slug (hence cannot match the regexp pattern which requires at least one character)

netbox=# select * from extras_tag;
 id | name | slug | color  | comments |  created   |         last_updated
----+------+------+--------+----------+------------+-------------------------------
  1 | temp | temp | 9e9e9e |          | 2019-10-12 | 2019-10-12 16:56:36.745793+00
  2 | 台灣 |      | 9e9e9e |          | 2019-11-18 | 2019-11-18 08:07:13.025115+00
(2 rows)

I also find I get this exception at the home page (/), but not at /dcim/devices/.

Cleanup

netbox=# delete from extras_taggeditem where tag_id in (select id from extras_tag where slug='');
DELETE 1
netbox=# delete from extras_tag where slug='';
DELETE 1

The exception persists for 15 minutes or until you invalidate the cacheops cache:

cd /opt/netbox/netbox
python3 manage.py nbshell
>>> import cacheops
>>> cacheops.invalidate_all()

Links

Reported previously as #2853, #3079, #3717 (insufficient detail to reproduce).

Reported on the google group here, here, here, here.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 18 (18 by maintainers)

Most upvoted comments

Slugify with allow_unicode=True is the better way If we want to keep the meaning of tags. unidecode handle only Chinese / partial Japanese? meaning.

Here is the sample of Japanese. Modern browsers can be resolve the escapaed URL characters.

>>> Tag.objects.get(pk=1)
<Tag: こんにちは>
>>> Tag.objects.get(pk=1).get_absolute_url()
'/extras/tags/%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF/'
>>>

If there is no objections, I would like to implement it.

This looks to be a simple missing dependancy of TagBase for “unidecode”, as otherwise slugify() in TagBase just returns the “tag” without any cleanup.

Will ponder how to best deal with this.