简体   繁体   中英

Compare Django-taggit tags from multiple queries and list objects from matching tags

I have a site that sells parts and tools. The site was originally built with separate models for tools and documents for those tools. The documents were just iterated over on a document page and linked to from the tool page. We use Django-taggit to tag everything, but I have tagged myself into a corner :)

I need to list the documents that belong to a particular tool, on the tool detail page and not on separate document page.

The problem is there is no relationship with the documents to the tool, so I am trying to query the tags on the tool and the tags on the documents and any document that has the same tag as the tool, would be listed on the page.

Below is what I've come up with so far and it works in the sense that it matches the tags, but it duplicates every document. For example, if I have tag names "one" and "two" on both the tool and the documents, it will list all matching documents multiplied by the number of matched tags. I hope that makes sense... I've also included a screenshot to show an example. I know why my code is duplicating, but my Python chops are not seasoned enough to write the code needed to solve it(I also know this can be written dryer - that's my next challenge). Thank you for your help.

在此处输入图片说明

View

def tool_detail(request, tool):
  contact_form(ContactForm, request)
  tags = Tool.tags.all()
  tool = get_object_or_404(Tool, slug=tool)
  uploads = tool.uploads.all()
  doc = Document.objects.all()
  return render(request, 'products/tool_detail.html', {'tool': tool, 'tags': tags, 'doc': doc, 'form': ContactForm, 'uploads': uploads})

Template

...
<tbody>
  {% for d in doc %}
    {% for tag in tool.tags.all %}
        {% if tag.name in d.tags.get.name %}
           <tr>
             <td>{{ d.title }}</td>
             <td style="text-align: center;"><a href="{{ d.file.url }}"><i class="fa fa-cloud-download"></i></a></td>
           </tr>
       {% endif %}
    {% endfor %}
 {% endfor %}
</tbody>
...

First of all, it's a bad practice placing your business logic in template - it should be done in view. Having said that, on to your question. First - the view (see comments in code):

def tool_detail(request, tool):
    contact_form(ContactForm, request)
    tags = Tool.tags.all()
    tool = get_object_or_404(Tool, slug=tool)
    uploads = tool.uploads.all()
    # filter the documents to find the ones that have identical tags,
    # add .distinct() to filter out duplicate documents
    doc = Document.objects.filter(tags__in=tool.tags.all()).distinct()
    return render(request, 'products/tool_detail.html', {'tool': tool, 'tags': tags,  'doc': doc, 'form': ContactForm, 'uploads': uploads})

and the form would simply be:

...
<tbody>
    {% for d in doc %}
        <tr>
            <td>{{ d.title }}</td>
                <td style="text-align: center;"><a href="{{ d.file.url }}"><i class="fa fa-cloud-download"></i></a>
            </td>
        </tr>
    {% endfor %}
</tbody>
...

Read more about filtering and field lookups in the documentation .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM