0

I have a sorted QuerySet I am passing to a template via dict. I need to maintain the QuerySet sort order through the dict to dynamically populate a table.

I am attempting to solve this problem via a nested list as suggested by This Answer. I have appended this solution with This Suggestion.

After Apache2 restart - the first load of the table has the correct sort. Once i click refresh, the sort is disrupted. I can click refresh multiple times and eventually get the sort back, but... Another Apache restart resets the sort order to expected.

Can anybody help me? Thx.

UPDATE:

Please, note finished_case is a foreign key. finished_case also inherits a Meta class attribute ordering = ['name']. But i also explicitly .order_by('finished_case__name').

views.url:

def caseindex(request):
    qtylist = caseStockOnHand(request)
    srtd = sorted(qtylist.items(), key=lambda item: item[0])
    context = {'qtyonhand':srtd}
    return render(request,'box_inv/caseindex.html', context)

methods.url:

def caseStockOnHand(request):
    s = stocktake.objects.filter(stocktake_type__name='Case').latest('date')
    c = caselog.objects.filter(date__gte=s.date)
    sd = stocktake_detail_case.objects.filter(stocktake=s).order_by('finished_case__name')

    qtylist = {}
    #Get Stocktake Qty
    for x in sd:
        qtylist[x.finished_case] = x.qty
    return qtylist

template.html:

{% for x, y in qtyonhand %}
        {% if y > 0 %}
        <tr class = {% cycle 'row1' 'row2' %}>
            <td>{{x}}</td>
            <td>{{y}}</td>
        </tr>
        {% endif %}
{% endfor %}

Also, I am using django 1.5, python 2.7, mysql 5.5, and Apache 2.2 with mod_wsgi on Debian Wheezy 7.5.

Community
  • 1
  • 1
N.Balauro
  • 151
  • 1
  • 1
  • 11

1 Answers1

1

Your example obviously doesn't represent your code, since you're using strings as dictionary keys and right after says that in your code they are not strings, but query sets. Trying to answer without the real code: You're using query sets as dictionary keys and their hash value (probably generated from their memory address) are being used to sort the final list. The query sets do not have a meaningful ordering, so after each reload you may see different results. Instead you need to sort using the query set contents.

Edit: Replace

qtylist[x.finished_case] = x.qty

With:

qtylist[x.finished_case.name] = x.qty

The former keys are finished_case objects and they don't have a meaningful ordering. The latter are strings and have the ordering you want.

Alternative: remove both the dict and the sort. The code becomes:

qtylist = []
for x in sd:
    qtylist.append((x.finished_case.name, x.qty))
return qtylist
hdante
  • 7,685
  • 3
  • 31
  • 36
  • I appreciate your input! The querysets are passed with an `order_by()`. From my understanding they are losing order because the `dict` type is unordered. So when i iterate through the `dict`, it gets ket values randomly? That is my understanding. Would gladly accpet being proven wrong :P In addition, in `'models.py` i am utilizing `Meta` subclasses with an `ordering`. – N.Balauro Jun 04 '14 at 16:00
  • Yes, they are losing order because the dict type is unordered. Additionally, they don't recover the order after the sort operation because you are not sorting them by name, you sort them by finished_case objects, which don't have a meaningful ordering. Response was expanded based on your updated code. – hdante Jun 04 '14 at 18:54
  • Excellent. I seemed to have tricked myself. Since calling`__unicode__(self)` returns `self.name` i forgot that in reality `x.finished_case` is an object and not a string. But... Can you elaborate on [this](https://docs.djangoproject.com/en/1.5/ref/models/options/#django.db.models.Options.ordering). This appears to state that the queryset should honor the ordering even when calling a list of objects. – N.Balauro Jun 04 '14 at 20:04
  • 1
    The query set honors the ordering, that is, the resulting list is ordered. Same for order_by(). You can verify this printing x in the loop above. That's why the alternative implementation that I sent above works: qtylist is ordered in the end of the loop. The ordering in the original code is broken, first, when inserting in the dict (becomes ordered by object hash() value, instead of name attribute) and, second, when using the sorted() function (becomes ordered by id() value, instead of name attribute). The best solution, then, is not to break the original ordering in the first place. – hdante Jun 04 '14 at 22:40