Ahmed Wagdi
Ahmed Wagdi

Reputation: 4371

Using distinct() with filter() in django

I'm trying to create a query in Django that calls unique rows (using distinct) that meet some condition of a filter (using filter)

here are the used files :

views.py

def cat_details(request, pk):
    current_user = request.user
    selected_cat = get_object_or_404(Category, pk=pk)
    selected_items = ItemIn.objects.all().filter(item_category=selected_cat).values_list('item_name', flat=True).distinct()
    all_cats = Category.objects.all()
    cat_count = all_cats.count()
    item_count = ItemIn.objects.values_list('item_name', flat=True).distinct().count()  # returns a list of tuples..
    #all_units = Item.objects.aggregate(Sum('item_quantity'))['item_quantity__sum']
    context = {
        #'all_units': all_units,
        'item_count': item_count,
        'cat_count': cat_count,
        'selected_items': selected_items,
        'selected_cat': selected_cat,
        'current_user': current_user,
    }

    return render(request, 'townoftech_warehouse/cat_details.html', context)

The variable called selected_items is where the problem!

and here is how I used this view function

HTML

{% extends 'townoftech_warehouse/base.html' %}
    {% block content %}
{% load static %}
        <div class="card">
  <div class="card-header">
    الاصناف فى المخزن
  </div>
  <div class="card-body">
      <h3 align="right"> {{ selected_cat }}</h3>
      <footer><a href="{% url 'edit_cat' selected_cat.pk%}"><button type="button" class="btn btn-dark">تعديل إسم الفئة</button></a>
     <a href="{% url 'category_delete' selected_cat.pk%}"><button type="button" class="btn btn-dark">مسح الفئة</button></a>
</footer>
  </div>
</div>
                  <div style="overflow: auto;height: 280px">

        <table class="table table-bordered">

  <tbody>
  {% for item in selected_items %}
    <tr align="right">
        <th scope="row"><a href = "{% url 'items' item.pk%}">{{ item.item_name }}</a></th>
    </tr>
  {% endfor %}
  </tbody>
</table>
                  </div>
        <br>
        <br>
<div align="right"><a href="{% url 'cat' %}"><button type="button" class="btn btn-danger">رجوع</button></a></div>

{% endblock %}

whenever I try to open this page the error I get is :

error

NoReverseMatch at /category/15/
Reverse for 'items' with arguments '('',)' not found. 1 pattern(s) tried: ['item\\/(?P<pk>[0-9]+)\\/$']

update

I've removed the link from the HTML files

changed

{% for item in selected_items %} {{ item.item_name }} {% endfor %}

to be like

  {% for item in selected_items %}
    <tr align="right">
        <th scope="row">{{ item.item_name }}</th>
    </tr>
  {% endfor %}

the error disappeared but it gives me a list of empty values now!

Upvotes: 0

Views: 28628

Answers (1)

neverwalkaloner
neverwalkaloner

Reputation: 47354

selected_items variable contains list of string objects(item names). String dont have pk attribute, so item.pk in template returns nothing.

Istead of values_list you neet pass to template list of objects. If you are using postgres you can use distinct() with argument.

selected_items = ItemIn.objects.all().filter(item_category=selected_cat).distinct('item_name')

Otherwise you can try to use values with 'item_name', 'pk':

selected_items = ItemIn.objects.all().filter(item_category=selected_cat).values('item_name', 'pk').distinct()

Upvotes: 12

Related Questions