radiac / django-tagulous Goto Github PK
View Code? Open in Web Editor NEWFabulous Tagging for Django
Home Page: http://radiac.net/projects/django-tagulous/
License: Other
Fabulous Tagging for Django
Home Page: http://radiac.net/projects/django-tagulous/
License: Other
It looks like the instructions for migrating to tagulous don't work correctly - in step 2 I don't think taggit (or tagging) is going to work in the data migration. I can't test this at the moment, but if that's the case we need to collect the tags directly, using the generic relations.
I had thought I'd tested that bit thoroughly at one point, so not sure how that got through - but because it's only in the docs there are no automated tests. Sorry! It should be possible to add some though.
I'm travelling at the moment, so it may take a couple of weeks for me to fix (patches welcome of course) - I'll update the docs in the meantime.
I'm trying to set tag tree models and I get the error
ValueError: Could not find manager CastTaggedUserManager in tagulous.models.tagged.
The TagTreeModel is:
class BusinessPhase(tagulous.models.TagTreeModel):
class TagMeta:
# Tag options
force_lowercase = True
And the model is:
class User(AbstractUser):
business_choices = tagulous.models.TagField(to=BusinessPhase)
Hi,
I just ran into another issue where the table name is added to the SQL query without quoting.
This causes PostGreSQL to throw fatal database errors if the table names have uppercase letters since PostGres will automatically lowercase unquoted table names. I'm working on a legacy Django project that uses camelcase in the app folder names. Simply renaming them is currently no solution as there seems to be no clean way to migrate. Even simply renaming the name property in the AppConfig seems to be a show stopper. Django itself handles this nicely (hence the table names with mixed case in the database).
A quick and simple way to resolve this is by simply adding double quotes around the table name in the SQL template as found in models.py on line 83:
# Build SQL
template = (
'%(floor)s((count*%(upper)d)/'
'(SELECT MAX(count) FROM "%(table)s")' # <-- added quotes
')+%(lower)d'
)
Just like the other issue I reported today, these seem like quick fixes imo (but I'm no expert so I could be wrong).
Maybe I'll even dare to fork and create a PR (despite me being a total python noob).
Kind regards,
Erik
I've tried both django-easy-select2 and django-select2 and this library breaks with both of them.
I cant get tagulous to work with any other admin select2 widgets. Compatibility would be nice.
For what its worth, as much as I like Tagulous more, this has forced me to abandon using Tagulous on a brand new project and switch to another library with the hope I can migrate to Tagulous in future.
I have set up an app with tagulous which works fine. However, I now have another app in a completely different django instance that has read-only access to the first apps database. This is so statistical data from the first app can be viewed in the second app.
Trouble is I can't get the second app to work at all when the code from the first app with the tagulous models is added in. I just get:
ValueError: Cannot set tag options on explicit tag model <class 'action_tool.models.ActionToolTreeTag'>
Any ./manage.py command returns the error.
In the first app I have:
class ActionToolTreeTag(TagTreeModel):
class TagMeta:
protected = True
class Action(models.Model):
primary_tags = TagField(to=ActionToolTreeTag, blank=True, null=True, related_name='primary')
secondary_tags = TagField(to=ActionToolTreeTag, blank=True, null=True, related_name='secondary')
That all works ok in the first app. The first app is installed in the second django instance and has a database router routing it to the first app db.
Any pointers appreciated!
Thanks!
I did not see an easy option to disallow the user to create new items, but only select existing ones.
Documentation seems to be missing notes on how to include the form.media
and the need to run collectstatic
(or at least if it's there it's not obvious).
As noted in #55 and at https://vevurka.github.io/dsp17/python/django/tagging/
Thanks for another tagging library and i am not being sarcastic!
"Based on ForeignKey and ManyToManyField, so it's easy to query" is a big selling point for me, so I was surprised to see, that giving a custom through
model is not possible.
When I remove the code "forbidding" that, all I need still seems to work. What is the reason behind forbidding custom through
models? What side-effects should I be aware of when circumventing the check?
Now that it works with 1.11, how about 2.0? Any stopping issues?
Following the procedures associated with starting up the example project, I've run into several blocking problems.
First, to establish context that I'm starting in a clean virtualenv:
quantum wam-homedir:master! ~/projs $ virtualenv -p /usr/bin/python3.7 tagulous-exampleRunning virtualenv with interpreter /usr/bin/python3.7
Using base prefix '/usr'
/usr/lib/python3/dist-packages/virtualenv.py:1086: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses
import imp
New python executable in /home/wam/projs/tagulous-example/bin/python3.7
Also creating executable in /home/wam/projs/tagulous-example/bin/python
Installing setuptools, pkg_resources, pip, wheel...done.
quantum wam-homedir:master! ~/projs $ cd tagulous-example
/home/wam/projs/tagulous-example
quantum wam-homedir:master! ...s/tagulous-example $ source bin/activate
(tagulous-example) quantum wam-homedir:master! ...s/tagulous-example $ pip install "Django>=1.8,<1.9"
Collecting Django<1.9,>=1.8
Downloading https://files.pythonhosted.org/packages/96/b9/b4108da1275dc2ac1bba1e87739cb31b3d44339affb83b0e949fb09c2bef/Django-1.8.19-py2.py3-none-any.whl (6.2MB)
100% |████████████████████████████████| 6.2MB 2.4MB/s
Installing collected packages: Django
Successfully installed Django-1.8.19
pip install -e git+https://github.com/radiac/django-tagulous.git#egg=django-tagulous
(tagulous-example) quantum wam-homedir:master! ...s/tagulous-example $ pip install -e git+https://github.com/radiac/django-tagulous.git#egg=django-tagulous
Obtaining django-tagulous from git+https://github.com/radiac/django-tagulous.git#egg=django-tagulous
Cloning https://github.com/radiac/django-tagulous.git to ./src/django-tagulous
Installing collected packages: django-tagulous
Running setup.py develop for django-tagulous
Successfully installed django-tagulous
(tagulous-example) quantum wam-homedir:master! ...s/tagulous-example $ cd src/django-tagulous/example
(tagulous-example) quantum django-tagulous:develop ...o-tagulous/example $ python manage.py migrate
Operations to perform:
Synchronize unmigrated apps: messages, staticfiles, tagulous
Apply all migrations: contenttypes, auth, admin, sessions, example
Synchronizing apps without migrations:
Creating tables...
Running deferred SQL...
Installing custom SQL...
Running migrations:
Rendering model states... DONE
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying example.0001_initial... OK
Applying sessions.0001_initial... OK
(tagulous-example) quantum django-tagulous:develop ...o-tagulous/example $ python manage.py createsuperuser
Username (leave blank to use 'wam'): wam
Email address: MY_EMAIL
Password:
Password (again):
Superuser created successfully.
Here's where the issues begin:
(tagulous-example) quantum django-tagulous:develop ...o-tagulous/example $ python manage.py initial_tags
Loading initial tags for example.Person.title
Traceback (most recent call last):
File "/home/wam/projs/tagulous-example/lib/python3.7/site-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "/home/wam/projs/tagulous-example/lib/python3.7/site-packages/django/db/backends/sqlite3/base.py", line 318, in execute
return Database.Cursor.execute(self, query, params)
sqlite3.OperationalError: no such table: example_tagulous_person_title
I've deleted the longer exception because the fundamental problem is the missing table. So I figured the problem was just a missing migration that didn't get committed, so I'd recreate:
(tagulous-example) quantum django-tagulous:develop ...o-tagulous/example $ python manage.py makemigrations
Did you rename the example._Tagulous_Person_hobbies model to Tagulous_Person_hobbies? [y/N] y
Did you rename the example._Tagulous_Person_title model to Tagulous_Person_title? [y/N] y
Migrations for 'example':
0002_auto_20181113_2314.py:
- Rename model _Tagulous_Person_hobbies to Tagulous_Person_hobbies
- Rename model _Tagulous_Person_title to Tagulous_Person_title
- Alter field title on person
So far, so good:
(tagulous-example) quantum django-tagulous:develop ...o-tagulous/example $ python manage.py migrate
Operations to perform:
Synchronize unmigrated apps: tagulous, messages, staticfiles
Apply all migrations: auth, admin, contenttypes, sessions, example
Synchronizing apps without migrations:
Creating tables...
Running deferred SQL...
Installing custom SQL...
Running migrations:
Rendering model states... DONE
Applying example.0002_auto_20181113_2314...Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/home/wam/projs/tagulous-example/lib/python3.7/site-packages/django/core/management/__init__.py", line 354, in execute_from_command_line
utility.execute()
File "/home/wam/projs/tagulous-example/lib/python3.7/site-packages/django/core/management/__init__.py", line 346, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/wam/projs/tagulous-example/lib/python3.7/site-packages/django/core/management/base.py", line 394, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/wam/projs/tagulous-example/lib/python3.7/site-packages/django/core/management/base.py", line 445, in execute
output = self.handle(*args, **options)
File "/home/wam/projs/tagulous-example/lib/python3.7/site-packages/django/core/management/commands/migrate.py", line 222, in handle
executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial)
File "/home/wam/projs/tagulous-example/lib/python3.7/site-packages/django/db/migrations/executor.py", line 110, in migrate
self.apply_migration(states[migration], migration, fake=fake, fake_initial=fake_initial)
File "/home/wam/projs/tagulous-example/lib/python3.7/site-packages/django/db/migrations/executor.py", line 148, in apply_migration
state = migration.apply(state, schema_editor)
File "/home/wam/projs/tagulous-example/lib/python3.7/site-packages/django/db/migrations/migration.py", line 115, in apply
operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
File "/home/wam/projs/tagulous-example/lib/python3.7/site-packages/django/db/migrations/operations/fields.py", line 201, in database_forwards
schema_editor.alter_field(from_model, from_field, to_field)
File "/home/wam/projs/tagulous-example/lib/python3.7/site-packages/django/db/backends/base/schema.py", line 484, in alter_field
old_db_params, new_db_params, strict)
File "/home/wam/projs/tagulous-example/lib/python3.7/site-packages/django/db/backends/sqlite3/schema.py", line 203, in _alter_field
self._remake_table(model, alter_fields=[(old_field, new_field)])
File "/home/wam/projs/tagulous-example/lib/python3.7/site-packages/django/db/backends/sqlite3/schema.py", line 140, in _remake_table
self.create_model(temp_model)
File "/home/wam/projs/tagulous-example/lib/python3.7/site-packages/django/db/backends/base/schema.py", line 250, in create_model
to_table = field.rel.to._meta.db_table
AttributeError: 'str' object has no attribute '_meta'
(1)
And it's all gone to crap. Keep in mind, this is the example project, using the build procedure specified in the documentation at: https://github.com/radiac/django-tagulous/tree/master/example
hi, does not support the new django 1.11 version?
i have this problem:
ERRORS:
core._Tagulous_Ideas_tags: (models.E023) The model name '_Tagulous_Ideas_tags' cannot start or end with an underscore as it collides with the query lookup syntax.
The command "python manage.py migrate" failed and exited with 1 during .
thanks
When I loop over a list of objects that have a tag field, the reload method in TagRelatedManagerMixin is triggering a database lookup for every object.
Example of the query:
SELECT "games_location"."id", "games_location"."name", "games_location"."slug", "games_location"."count", "games_location"."protected", "games_location"."title", "games_location"."content" FROM "games_location" INNER JOIN "games_game_location" ON ("games_location"."id" = "games_game_location"."location_id") WHERE"games_game_location"."game_id" = '8' Duplicated 7 times. | 4.349717268377556% | 0.50 | SelExpl
...
E:\vm\venv\churchworthy\lib\site-packages\tagulous\models/managers.py in reload(486)
self.tags = list(self.all())
Because self.all()
is being forced into a list, it's executing the query for each Game object. Normally I would use prefetch_related()
to cut down on database calls but this is preventing it from actually helping. I'm not totally clear on what the reload method does for me when I'm just querying tags and not saving anything.
Hi,
I noticed I kept getting a division by zero error from the Django ORM when trying to fetch the tags with weights if no tagged items exist. The error comes from the SQL query and is reproducible on the database level.
tags = SomeModel.tags.tag_model.objects.weight()
throws: django.db.utils.DataError: division by zero
try - catch doesn't seem to help either
SELECT (FLOOR((count*5)/(SELECT MAX(count)
Simply adding one tagged item solves this issue.
Rewriting the query as follows solves this issue as well (as dividing by NULL yields NULL), returning weight: NULL if no tagged items exist
SELECT (FLOOR((count*5)/(SELECT NULLIF(MAX(count), 0)
I'm just a Django / Python beginner so I don't really know how to address this issue properly. As far as I can tell, NULLIF seems standard SQL syntax and does work on my local PGSQL server.
Kind regards,
Erik
I am trying to filter using tags created with taguluous. However, when using the Q object to filter the tags, it comes up with this error
Exception Value: invalid literal for int() with base 10: '(my tag)'
where the line of code the error appears is in :
recipe_list= RecipePage.objects.filter(Q(recipeName__icontains = word) | **Q(tags = word)**)
In my models.py:
class RecipePage(models.Model):
user = models.ForeignKey(CustomUser)
recipeName = models.CharField(max_length=100)
tags = TagField(
force_lowercase=True,
max_count=5,
)
Let me know if there's another or better way to use multiple arguments to filter my queryset!
Thank you!
Hi,
I have a very simple model and tried to implement tagulous. It all works fine except that I cannot access an object with tags within the Admin. It refers to both django-admin code as well as tagulous, that is why I am posting it here.
Environment:
Request Method: GET
Request URL: http://127.0.0.1:8000/admin/organizer/document/1/change/
Django Version: 1.10.1
Python Version: 3.4.3
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'tagulous',
'organizer']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Template error:
In template /home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/contrib/admin/templates/admin/change_form.html, error at line 33
object of type 'FakeQuerySet' has no len() 23 : {% endblock %}
24 : {% endif %}
25 :
26 : {% block content %}<div id="content-main">
27 : {% block object-tools %}
28 : {% if change %}{% if not is_popup %}
29 : <ul class="object-tools">
30 : {% block object-tools-items %}
31 : <li>
32 : {% url opts|admin_urlname:'history' original.pk|admin_urlquote as history_url %}
33 : <a href=" {% add_preserved_ filters history_url %}" class="historylink">{% trans "History" %}</a>
34 : </li>
35 : {% if has_absolute_url %}<li><a href="{{ absolute_url }}" class="viewsitelink">{% trans "View on site" %}</a></li>{% endif %}
36 : {% endblock %}
37 : </ul>
38 : {% endif %}{% endif %}
39 : {% endblock %}
40 : <form {% if has_file_field %}enctype="multipart/form-data" {% endif %}action="{{ form_url }}" method="post" id="{{ opts.model_name }}_form" novalidate>{% csrf_token %}{% block form_top %}{% endblock %}
41 : <div>
42 : {% if is_popup %}<input type="hidden" name="{{ is_popup_var }}" value="1" />{% endif %}
43 : {% if to_field %}<input type="hidden" name="{{ to_field_var }}" value="{{ to_field }}" />{% endif %}
Traceback:
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/core/handlers/exception.py" in inner
39. response = get_response(request)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/core/handlers/base.py" in _get_response
217. response = self.process_exception_by_middleware(e, request)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/core/handlers/base.py" in _get_response
215. response = response.render()
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/response.py" in render
109. self.content = self.rendered_content
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/response.py" in rendered_content
86. content = template.render(context, self._request)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/backends/django.py" in render
66. return self.template.render(context)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/base.py" in render
208. return self._render(context)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/base.py" in _render
199. return self.nodelist.render(context)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/base.py" in render
994. bit = node.render_annotated(context)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/base.py" in render_annotated
961. return self.render(context)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/loader_tags.py" in render
174. return compiled_parent._render(context)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/base.py" in _render
199. return self.nodelist.render(context)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/base.py" in render
994. bit = node.render_annotated(context)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/base.py" in render_annotated
961. return self.render(context)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/loader_tags.py" in render
174. return compiled_parent._render(context)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/base.py" in _render
199. return self.nodelist.render(context)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/base.py" in render
994. bit = node.render_annotated(context)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/base.py" in render_annotated
961. return self.render(context)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/loader_tags.py" in render
70. result = block.nodelist.render(context)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/base.py" in render
994. bit = node.render_annotated(context)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/base.py" in render_annotated
961. return self.render(context)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/loader_tags.py" in render
70. result = block.nodelist.render(context)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/base.py" in render
994. bit = node.render_annotated(context)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/base.py" in render_annotated
961. return self.render(context)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/defaulttags.py" in render
209. nodelist.append(node.render_annotated(context))
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/base.py" in render_annotated
961. return self.render(context)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/loader_tags.py" in render
210. return template.render(context)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/base.py" in render
210. return self._render(context)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/base.py" in _render
199. return self.nodelist.render(context)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/base.py" in render
994. bit = node.render_annotated(context)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/base.py" in render_annotated
961. return self.render(context)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/defaulttags.py" in render
209. nodelist.append(node.render_annotated(context))
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/base.py" in render_annotated
961. return self.render(context)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/defaulttags.py" in render
209. nodelist.append(node.render_annotated(context))
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/base.py" in render_annotated
961. return self.render(context)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/defaulttags.py" in render
315. return nodelist.render(context)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/base.py" in render
994. bit = node.render_annotated(context)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/base.py" in render_annotated
961. return self.render(context)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/defaulttags.py" in render
315. return nodelist.render(context)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/base.py" in render
994. bit = node.render_annotated(context)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/base.py" in render_annotated
961. return self.render(context)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/base.py" in render
1050. return render_value_in_context(output, context)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/template/base.py" in render_value_in_context
1028. value = force_text(value)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/utils/encoding.py" in force_text
76. s = six.text_type(s)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/utils/html.py" in <lambda>
391. klass.__str__ = lambda self: mark_safe(klass_str(self))
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/forms/boundfield.py" in __str__
43. return self.as_widget()
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/forms/boundfield.py" in as_widget
101. return force_text(widget.render(name, self.value(), attrs=attrs))
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/django/forms/boundfield.py" in value
137. return self.field.prepare_value(data)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/tagulous/forms.py" in prepare_value
290. return super(TagField, self).prepare_value(value)
File "/home/kev/.virtualenvs/papermaster/lib/python3.4/site-packages/tagulous/forms.py" in prepare_value
163. if len(value) != 1:
Exception Type: TypeError at /admin/organizer/document/1/change/
Exception Value: object of type 'FakeQuerySet' has no len()
Hi again,
I have a tags = TagField( autocomplete_view='story_tags_autocomplete') field in my model.
I want to implement this widget - from the admin, in a user facing page
After having looked at the example project and the docs, I cannot figure out how to code the template. I have also looked at the select2.js docs. An ordinary jquery ajax call gives me the tags but from there I am stuck.
Can you add this as an example to the example? It would look nice
Thanks
Django Version: 1.10.4
Exception Type: IntegrityError
Exception Value:
(1062, "Duplicate entry '________1' for key 'news__tagulous_news_tags_slug_efde0cb2_uniq'")
Exception Location: C:\Program Files\Python35\lib\site-packages\pymysql\err.py in _check_mysql_exception, line 112
Python Executable: C:\Program Files\Python35\python.exe
Python Version: 3.5.1
n.tags = 'комедия', 'криминал'
n.save()
OK
if update tags:
n.tags = 'комедия', 'криминал', 'Миронов', 'Табаков'
n.save()
ERROR
in phpmyadmin slug field: ________
We would like to set up our tag field such that only existing tags (defined by staff) can be selected. We do not want users to be able to add new tags. Is this possible with this library? I've read through the documentation and it's unclear to me whether this library actually supports it.
Thanks!
The max slug length of 255 seems reasonable for tag fields, but that could quickly lead to some very long paths in tag trees. If we take 2000 chars as the upper URL limit, we can set a default of 1900 to allow for most options, and document that the start of a path URL can only safely be 100 chars long.
The main problem with this is that paths are auto-generated, so we have to manage this automatically. I suggest that once a path gets to eg 500 characters its no longer human-readable anyway, so instead of using tag slugs in the path, we use tag ids (for the children of the first tag to break the 500 char limit).
These limits will be configurable as site-wide settings. Upgrade instructions will need to warn of the change.
It is not obvious that users should use the delete key to clear a SingleTagField. Users sometimes try to erase the field with the space bar, which makes it appear blank, thus creating a tag of " ". I have had to work around this by strip() and converting "" to None in my form's clean method. If there is no case where " " is a useful tag, this could be built in to the library.
Hello
I have just installed django-tagulous and everything is working fine until I have this line:
autocomplete_view='story_tags_autocomplete'
Here is my model:
class Story(Model):
...
tags = TagField(
autocomplete_view='story_tags_autocomplete'
)
Here is the relevant urls.py lines:
from tagulous.views import autocomplete
url(r'^story/tags/autocomplete/', autocomplete, {'tag_model': Story}, name='story_tags_autocomplete'),
Here is a picture of what happens in the admin:
Here is the traceback:
Internal Server Error: /story/tags/autocomplete/
Traceback (most recent call last):
File "/Users/adam/PycharmProjects/venv/lib/python2.7/site-packages/django/core/handlers /exception.py", line 41, in inner
response = get_response(request)
File "/Users/adam/PycharmProjects/venv/lib/python2.7/site-packages/django/core/handlers/base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/Users/adam/PycharmProjects/venv/lib/python2.7/site-packages/django/core/handlers/base.py", line 185, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/adam/PycharmProjects/venv/lib/python2.7/site-packages/tagulous/views.py", line 44, in autocomplete
options = tag_model.tag_options
AttributeError: type object 'Story' has no attribute 'tag_options'
[31/Jul/2018 10:46:02] "GET /story/tags/autocomplete/?q=&p=1&=1533059158650 HTTP/1.1" 500 16428
thanks
We use Tagulous as well as Django Model Utils's FieldTracker
FieldTracker checks which fields have changed as a model instance is saved, which we use for revision logging. FieldTracker offers a has_changed
method to see if a field has changed in a save()
operation. That function compares the field instance before and after a model instance save()
operation. However, for a newly created model instance, the first instance of the field will be None. So has_changed
compares None
to a new Tag instance. Tagulous _eq
function (in class BaseTagRelatedManager(object)
in django-tagulous/tagulous/models/managers.py
) doesn't account for this case, which raises a TypeError 'NoneType' object is not iterable
in other_tags = [six.text_type(tag).lower() for tag in other]
.
Would be great if we can add a check in there for this case so it plays together more nicely with other Django apps?
How to set required=False ?
By default every field is set required=True form my Model.
Cannot find in docs where to set required=False
I wasn't able to add a Tag field to an Abstract Base Class model so that all child models would have tags.
It seems to cause something to clash and nothing works, django's management commands start to fail and produce this error.
File "/media/techdragon/Files/dev/sources/myapp/news/models.py", line 35, in <module>
class NewsVideo(News):
File "/home/techdragon/.pyenv/versions/myapp/lib/python3.4/site-packages/django/db/models/base.py", line 276, in __new__
new_class.add_to_class(field.name, new_field)
File "/home/techdragon/.pyenv/versions/myapp/lib/python3.4/site-packages/django/db/models/base.py", line 324, in add_to_class
value.contribute_to_class(cls, name)
File "/home/techdragon/.pyenv/versions/myapp/lib/python3.4/site-packages/tagulous/models/fields.py", line 447, in contribute_to_class
super(TagField, self).contribute_to_class(cls, name)
File "/home/techdragon/.pyenv/versions/myapp/lib/python3.4/site-packages/tagulous/models/fields.py", line 169, in contribute_to_class
"The tag field %r is already attached to a model" % self
AttributeError: The tag field <tagulous.models.fields.TagField: tags> is already attached to a model
See the Django documentation change: django/django@4f83bfa
And the closed ticket: https://code.djangoproject.com/ticket/2495
Hi,
I have updated the version of my project for django 2.1, and I am having problem to render forms, I get error :
TypeError: render () got an unexpected keyword argument 'renderer'
Django 2.1 release says, Feature removed in 2.1:
"Support for Widget.render ( ) methods without the renderer argument is removed. "
if it's helpful, I've managed to solve it, modifying the method "render" of the class "TagWidgetBase", I have added "renderer=None" in tagulous / forms.py:
def render (self, name, value, attrs = {}, renderer=None):
if this solution is correct to fix this problem, you can accept my pr?
thanks.
Hi to everyone. I would like to save a list og tags to the model overriding the save_model()
en the Django Admin.
I have this:
def save_model(self, request, obj, form, change):
obj.tags = a_list_of_tags
obj.save()
super(VideoAdmin, self).save_model(request, obj, form, change)
But it don't works. I'm doing bad?
Hi,
I've run accross a small problem while trying to create a Tag. I've defined my own Tag model as such :
class Tag(TagTreeModel):
class TagMeta:
protect_all = True
Then if I try to save a tag without a name I get an IndexError
while I would expect and IntegrityError
:
>>> Tag().save()
Traceback (most recent call last):
File "<input>", line 1, in <module>
Tag().save()
File "/srv/http/venv/lib/python2.7/site-packages/tagulous/models/models.py", line 711, in save
self.label = parts[-1]
IndexError: list index out of range
This is not a big issue but if I was trying to catch that error I would not expect this one since Tag.name is a non null field.
Hi,
Thanks for your app, I have managed to use it well so far.
But now I am facing the following problem; if I try to set a list to the attribute tags of my model, only the last will be related with the holding model.
I have an archive model with a tag fild.
archive.__setattr__('tags', extracted_tags[:5]) *mode code* archive.save()
Where extracted_tags is a list of strings, comma separated.
It saves the tags, and i can see all of them at django admin as well on my app, but only the last of them is really related to the model.
Imagine extracted tags are "ec2" , "shard", "amazon", "aws" and "mongodb".
Doing queries like the following:
Archive.objects.filter(tags="ec2")
returns nothing []
But:
Archive.objects.filter(tags="mongodb")
[<Archive: AWS_NoSQL_MongoDB>
Strange because doing:
Archive.tags.tag_model.objects.all()
gives:
[<_Tagulous_Archive_tags: amazon web services>, <_Tagulous_Archive_tags: aws>, <_Tagulous_Archive_tags: ebs>, <_Tagulous_Archive_tags: ec2>, <_Tagulous_Archive_tags: mongodb>
But asking for :
Archive.tags.tag_model.objects.filter(name="mongodb")
return:
[<_Tagulous_Archive_tags: mongodb>]
But asking for:
Archive.tags.tag_model.objects.filter(name="shard")
[]
Very rare....
And so on for the other 3 properties. So only the last tagged inserted is really related to the model, despite the fact all of them appear at the admin and in my views under that "archive" model.
The error on the title of this issue is because whenever I open shell_plus and try to save an archive, even without specifying tags, it says i cant save because is a CastTaggedQuerySet, eventhough i just do:
a = Archive.objects.filter(title="AWS_NoSQL_MongoDB")
In the other hand, when i check those tags in postgres, int he table appname__tagulous_archive_tags , the table appnamea_archive_tags, etc, all is well related, and seems to be OK.
Following above example: "shard" is id 63 related with archive_id 27, so it looks fine but somehow, something is not working properly.
Could you help me please?
Thanks
I am trying to find the way to have the UI changing effect when I press enter after inputting a tag (which also comes with a cross to delete the tag) instead of typing comma. I saw that implemented in the example but not sure how is it done. My model and form are as below:
class UserProfile(models.Model):
..........
subjectTags = tagulous.models.TagField(to=SubjectTags)
class CompleteProfileCTutorForm(forms.ModelForm):
phone_number = forms.CharField(max_length = 12)
bio = forms.CharField(max_length = 500, widget=forms.Textarea)
avatar = forms.ImageField(required=False)
subjectTags = tagulous.models.TagField()
class Meta:
model = UserProfile
fields = [
'phone_number',
'bio',
'subjectTags',
'avatar',
]
exclude = ('user',)
Thanks for your help in advance.
I have inherited model (through PolymorphicModel https://github.com/chrisglass/django_polymorphic):
from django.db import models
from polymorphic import PolymorphicModel
from tagulous.models import TagField
class Event(PolymorphicModel):
name = models.CharField(max_length=40, blank=False, null=False)
datetime = models.DateTimeField()
tags = TagField()
class UpdateUpload(Event):
destination = models.CharField(max_length=20, default=None)
product = models.CharField(max_length=30, default=None)
subproduct = models.CharField(max_length=20, default=None, blank=True, null=True)
When I use the Django-admin, I can set the tags for the parent model "Event" and for the model "UpdateUpload".
But when I try to set the tags 'manually' in the child model (see below), the tags are not set / changed:
>>> ins = UpdateUpload.objects.get(pk=253)
>>> ins
<UpdateUpload: 20151023-test-1.7.1-release>
>>> ins.tags
<django.utils.deprecation.TagRelatedManager object at 0x063305F0>
>>> ins.tags.all()
[<_Tagulous_Event_tags: test>, <_Tagulous_Event_tags: release>, <_Tagulous_Event_tags: test>]
>>> ins.tags = ['test1', 'test2']
>>> ins.save()
>>> ins.tags.all()
[<_Tagulous_Event_tags: test>, <_Tagulous_Event_tags: release>, <_Tagulous_Event_tags: test>]
>>> ins.tags = 'test1, test2'
>>> ins.save()
>>> ins.tags.all()
[<_Tagulous_Event_tags: test>, <_Tagulous_Event_tags: release>, <_Tagulous_Event_tags: test>]
With the parent model, it is working:
>>> inse = Event(name='testevent', datetime=datetime.now())
>>> inse
<Event: testevent>
>>> inse.tags = ['test', 'test1']
>>> inse.save()
>>> inse
<Event: testevent>
>>> inse.tags.all()
[<_Tagulous_Event_tags: test>, <_Tagulous_Event_tags: test1>]
Tag field throws an error if string is long (greater than 50):
DatabaseError: value too long for type character varying(50)
So i cannot save data. How to set max_length of tag field greater than 50 ?
The same problem with simple fields on SO:
http://stackoverflow.com/questions/3803552/django-fixture-fails-stating-databaseerror-value-too-long-for-type-character
Hello,
I can't get Tagulous working on my server. After I install Tagulous (via pip) and run python manage.py makemigrations, I get this error:
Traceback (most recent call last):
File "manage.py", line 10, in
execute_from_command_line(sys.argv)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/init.py", line 367, in execute_from_command_line
utility.execute()
File "/usr/local/lib/python2.7/dist-packages/django/core/management/init.py", line 341, in execute
django.setup()
File "/usr/local/lib/python2.7/dist-packages/django/init.py", line 27, in setup
apps.populate(settings.INSTALLED_APPS)
File "/usr/local/lib/python2.7/dist-packages/django/apps/registry.py", line 108, in populate
app_config.import_models(all_models)
File "/usr/local/lib/python2.7/dist-packages/django/apps/config.py", line 199, in import_models
self.models_module = import_module(models_module_name)
File "/usr/lib/python2.7/importlib/init.py", line 37, in import_module
import(name)
File "/usr/local/lib/python2.7/dist-packages/tagulous/models/init.py", line 23, in
from tagulous.models import migrations
File "/usr/local/lib/python2.7/dist-packages/tagulous/models/migrations.py", line 286, in
south_support()
File "/usr/local/lib/python2.7/dist-packages/tagulous/models/migrations.py", line 199, in south_support
from south import modelsinspector
File "/usr/lib/python2.7/dist-packages/south/modelsinspector.py", line 20, in
from django.contrib.contenttypes import generic
ImportError: cannot import name generic
I can't figure out why. It works on my dev server but it won't work on my Ubuntu server (digital ocean). I've attached my requirements. Also note that I've switched to django version 1.10 as it says in Tagulous documentation that is the newest supported version. Also note that I am using Python 2.7 on my Ubuntu server but using python 34 on my development server. That is the only difference I can see.
It would be better if the slug max length is a setting, not hardcoded to 255. Slugifier should also take this into account.
If I have a SingleTagField on model, like this
engine = SingleTagField()
I get this error when attempting to create an object with that model
File "/Users/jeanne/Env/phobeus_env/lib/python3.7/site-packages/tagulous/models/descriptors.py", line 133, in get_manager
manager = SingleTagManager(self, instance)
File "/Users/jeanne/Env/phobeus_env/lib/python3.7/site-packages/tagulous/models/managers.py", line 49, in __init__
self.tag_cache = self.get_actual()
File "/Users/jeanne/Env/phobeus_env/lib/python3.7/site-packages/tagulous/models/managers.py", line 101, in get_actual
self.flush_cache()
File "/Users/jeanne/Env/phobeus_env/lib/python3.7/site-packages/tagulous/models/managers.py", line 64, in flush_cache
if hasattr(self.instance, cache_name):
File "/Users/jeanne/Env/phobeus_env/lib/python3.7/site-packages/tagulous/models/descriptors.py", line 143, in __get__
manager = self.get_manager(instance, instance_type)
File "/Users/jeanne/Env/phobeus_env/lib/python3.7/site-packages/tagulous/models/descriptors.py", line 133, in get_manager
manager = SingleTagManager(self, instance)
File "/Users/jeanne/Env/phobeus_env/lib/python3.7/site-packages/tagulous/models/managers.py", line 49, in __init__
self.tag_cache = self.get_actual()
File "/Users/jeanne/Env/phobeus_env/lib/python3.7/site-packages/tagulous/models/managers.py", line 101, in get_actual
self.flush_cache()
File "/Users/jeanne/Env/phobeus_env/lib/python3.7/site-packages/tagulous/models/managers.py", line 64, in flush_cache
if hasattr(self.instance, cache_name):
File "/Users/jeanne/Env/phobeus_env/lib/python3.7/site-packages/tagulous/models/descriptors.py", line 143, in __get__
manager = self.get_manager(instance, instance_type)
File "/Users/jeanne/Env/phobeus_env/lib/python3.7/site-packages/tagulous/models/descriptors.py", line 133, in get_manager
It repeats ad infinitum by nature of recursion, causing this error.
Can we upgrade select2 to version 4?
It looks as though it now supports defining a list of characters to stop parsing on eliminating some of the need for your monkeypatching.
I tried to modify your adapter code, but the significant changes in version 4 of select2 left me completely unable to work out how to update your adapter.
Example: paste, these, strings
Actually, I'm trying to save a tastypie model resource which contains a TagField
from django-tagulous
Here are my model, and resources:
# models.py
class SimpleModel(models.Model):
topics = tagulous.models.TagField()
title = models.CharField(max_length=100)
# resources.py
class TopicResource(ModelResource):
class Meta:
queryset = SimpleModel.topics.tag_model.objects.all()
authentication = Authentication()
authorization = Authorization()
class SimpleModelResource(ModelResource):
tags = fields.ToManyField(TopicResource, attribute='topics', full=True, null=True)
class Meta:
queryset = SimpleModel.objects.all()
authentication = Authentication()
authorization = Authorization()
the curl part:
curl --request POST --dump-header - --header 'Content-Type: application/json' --data '{"tags": ["/api/v1/topic/1/"], "title": "A bad dream"}' localhost:8000/api/v1/simplemodel/
The shell doesn't return any error, however, the tags are not associated with the new object.
By overriding the ModelResource save_m2m method
, before the super
call the tag object is present (print bundle.data['tags']), then in the super(SimpleModelResource, self).save_m2m(bundle)
tastypie looks for the related manager associated with the tags
field, the related_mngr
is returned but when it is evaluated using: if not related_mngr
it evaluates to True
skiping the m2m association.
I'm sorry if it isn't an issue for this repository, I'm was not sure, and maybe it must be posted in the django-tastypie repository.
I'm using Django 1.8.7 and have a model with several tagulous fields and with ForeignKeys pointing to it from other models.
When I serialize it (Article) like so:
data = serializers.serialize("xml", Article.objects.published()[:1])
And then deserialize it (test code):
for obj in serializers.deserialize("xml", data):
type(obj.object)
This exception is thrown:
File " ... /tagulous/models/tagged.py", line 414, in _detag_to_serializable
clone_field.contribute_to_class(FakeTaggedModel, field.name)
AttributeError: 'ManyToOneRel' object has no attribute 'contribute_to_class
If I comment out all references to Article in models that use it as a ForeignKey, the deserialization proceeds without throwing an Exception. It is when the ManyToOneRel fields are encountered that the exception occurs because these do not appear to have "contribute_to_class" attributes.
I can supply more information upon request, but the model is large and I'm hoping this is enough to reproduce the error. (Exception trace below.)
Thanks (I'm otherwise finding tagulous excellent).
EXCEPTION TRACE
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/home/nathan/workspace/gu/groundup/test.py", line 10, in <module>
for obj in serializers.deserialize("xml", data):
File "/home/nathan/workspace/gu/lib/python3.4/site-packages/django/core/serializers/xml_serializer.py", line 169, in __next__
return self._handle_object(node)
File "/home/nathan/workspace/gu/lib/python3.4/site-packages/tagulous/serializers/xml_serializer.py", line 63, in _handle_object
obj = super(Deserializer, self)._handle_object(node)
File "/home/nathan/workspace/gu/lib/python3.4/site-packages/django/core/serializers/xml_serializer.py", line 178, in _handle_object
Model = self._get_model_from_node(node, "model")
File "/home/nathan/workspace/gu/lib/python3.4/site-packages/tagulous/serializers/xml_serializer.py", line 74, in _get_model_from_node
Model = RealModel._detag_to_serializable()
File "/home/nathan/workspace/gu/lib/python3.4/site-packages/tagulous/models/tagged.py", line 413, in _detag_to_serializable
clone_field.contribute_to_class(FakeTaggedModel, field.name)
AttributeError: 'ManyToOneRel' object has no attribute 'contribute_to_class
``
Recreate: paste into example skills one, two, java
. It sticks on "searching", even though there are matching results.
If multiple tags have been pasted, it is likely complete, so should not search anyway.
In the url definition, {'tag_model': Person},
should be {'tag_model': Person.skills.tag_model}
Django 1.11.3
django-tagulous 0.13.2
class Media(models.Model):
tags = tagulous.models.TagField(
space_delimiter=False,
tree=True,
related_name='medias',
blank=True
)
>>> Media.tags.tag_model.objects.create(name='r')
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "D:\virtual_env\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "D:\virtual_env\lib\site-packages\django\db\models\query.py", line 394, in create
obj.save(force_insert=True, using=self.db)
File "D:\virtual_env\lib\site-packages\tagulous\models\models.py", line 711, in save
self.label = parts[-1]
IndexError: list index out of range
Looks like utils.split_tree_name
returns an empty list.
Maybe I am too dense, but I went over the documentation a few times and I cannot find how to use Tagulous in a regular Form that is not a ModelForm. Maybe I am missing something.
We are trying to have a search view that can be filtered by tag but cannot figure out how to set it up so Tagulous autocompletes from the right field in the right model. Anyone can point us in the right direction?
I followed the documentation at http://radiac.net/projects/django-tagulous/documentation/usage/#example_tag_trees but
$ python
Python 3.6.0 |Continuum Analytics, Inc.| (default, Dec 23 2016, 12:22:00)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import tagulous
>>> tagulous.__version__
'0.13.2'
>>> import lowfat.models
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/raniere/SSI/src/lowfat/lowfat/models.py", line 53, in <module>
class FundActivity(tagulous.models.TagTreeModel): # pylint: disable=model-no-explicit-unicode
AttributeError: module 'tagulous' has no attribute 'models'
I am currently using django 1.11.6, and when I tried to use tagulous, it says module object has no attributes 'models'. Is it because my version is too new? I have followed the steps of installation. If so, will there be support for it soon?
Thank you very much for your help in advance.
When using with Django REST Framework 3+ and specifying the model property with tagulous.models.TagField
a POST/PUT request via the Browsable API throws below error:
AttributeError at /api/calendar-item/1/
'list' object has no attribute 'pk'
/usr/local/lib/python3.6/site-packages/tagulous/models/managers.py in _ensure_tags_in_db, line 522
The DRF handles ManyToMany fields fine via API, by allowing requests to assign the related join to the entity being created/updated.
Can you add a seralizer extension method to allow POST/PUT requests to allow posting of the multiple "tag" primary keys to be saved against related entity; instead of expecting CSV string.
Something I would like is indexing support for the TagRelatedManager. This is for a case where a slug is passed to a view, and after grabbing the correct tags based on the slug, I want to also get the name of that respective tag. Like this
lang_name = Game.approved.filter(language__slug=lang_slug).first().language[lang_slug].name
It works on IE.
But when I type chinese words on chrome or safari, it keeps only the English letters in the inputbox .
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.