-
Bug
-
Resolution: Fixed
-
Low
-
Severity 3 - Minor
-
NOTE: This bug report is for Confluence Cloud. Using Confluence Server? See the corresponding bug report.
It looks like this bug has existed since we first forked OSQA. The simplest way to describe this bug is with an example:
>>> ## Retrieve a Tag >>> tag = Tag.objects.get(name='a_tag') >>> ## Find all questions that are tagged with this Tag >>> Question.objects.filter_state(deleted=False).filter(tags__id=tag.id) [<Question: Some Question>] >>> ## Take the first question in this list as an example >>> q = Question.objects.filter_state(deleted=False).filter(tags__id=tag.id)[0] >>> q <Question: Some Question> >>> ## Try to access all the tags that this question has by traversing the ManyToManyField defined on the Node model >>> q.tags.all() [] >>> ## An empty list is returned - this is clearly incorrect. We already established that this question has the 'a_tag' tag, as that's how we retrieved it in the first place. >>> ## The tagnames field is set correctly, though. >>> q.tagnames u'a_tag jira another_tag"
This bug has existed since the beginnings of Answers, and is undoubtedly a root cause behind a lot of weirdness we actually see when trying to build model filters.
This has also resulted in a lot of hacks in the UI where the list of tags against a question is manually built by splitting the 'tagnames' field and retrieving each tag individually.
The underlying cause of the problem is that we override the Django model Manager for all Node models, and set the use_for_related_fields setting to
{True}. This is contradictory to the recommendation in the Django docs, which says[1]:
Writing correct Managers for use in automatic Manager instances
As already suggested by the django.contrib.gis example, above, the use_for_related_fields feature is primarily for managers that need to return a custom QuerySet subclass. In providing this functionality in your manager, there are a couple of things to remember.
Do not filter away any results in this type of manager subclass
One reason an automatic manager is used is to access objects that are related to from some other model. In those situations, Django has to be able to see all the objects for the model it is fetching, so that anything which is referred to can be retrieved.
If you override the get_queryset() method and filter out any rows, Django will return incorrect results. Don’t do that. A manager that filters results in get_queryset() is not appropriate for use as an automatic manager.
[1]: https://docs.djangoproject.com/en/dev/topics/db/managers/#manager-types
Once this fix is pushed, there is potentially some low-hanging fruit that could be picked to improve performance in Answers by changing all our tag manipulation code to use the tags field instead of the tagnames field.
- is related to
-
CONFSERVER-46667 Node model entities cannot traverse related entities correctly
-
- Closed
-