Skip to content

Commit

Permalink
Revert removing __iter__() from TableData, (removed in 8fe9826).
Browse files Browse the repository at this point in the history
This fixes jieter#427, maybe also jieter#421 and jieter#361
  • Loading branch information
jieter authored and intiocean committed Feb 27, 2017
1 parent 8036d81 commit ab28669
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 61 deletions.
11 changes: 10 additions & 1 deletion django_tables2/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ def __getitem__(self, key):
'''
return self.data[key]

def __iter__(self):
'''
for ... in ... default to using this. There's a bug in Django 1.3
with indexing into querysets, so this side-steps that problem (as well
as just being a better way to iterate).
'''
return iter(self.data)

def get_model(self):
return getattr(self.data, 'model', None)

Expand Down Expand Up @@ -190,7 +198,7 @@ def order_by(self, aliases):

# custom ordering
if modified_any:
return True
return

# Traditional ordering
if accessors:
Expand Down Expand Up @@ -579,6 +587,7 @@ def paginate(self, klass=Paginator, per_page=None, page=1, *args, **kwargs):
`~django.core.paginator.PageNotAnInteger`) may be raised from this
method and should be handled by the caller.
'''

per_page = per_page or self._meta.per_page
self.paginator = klass(self.rows, per_page, *args, **kwargs)
self.page = self.paginator.page(page)
Expand Down
6 changes: 0 additions & 6 deletions tests/app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,6 @@ class PersonInformation(models.Model):
)


class Player(models.Model):
person = models.ForeignKey(Person)
created = models.DateTimeField(auto_now_add=True)
score = models.PositiveIntegerField()


# -- haystack -----------------------------------------------------------------


Expand Down
58 changes: 9 additions & 49 deletions tests/test_models.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
# coding: utf-8
from random import randint

import django_tables2 as tables
import pytest
from django.db.models.functions import Length
from django.utils import six
from django_tables2 import RequestConfig

import pytest

from .app.models import Occupation, Person, PersonProxy, Player
from .utils import build_request
from .app.models import Occupation, Person, PersonProxy
from .utils import assertNumQueries, build_request

pytestmark = pytest.mark.django_db
request = build_request('/')
Expand Down Expand Up @@ -406,58 +403,21 @@ class Meta:
assert Person.objects.get(pk=person1.pk) == person1
assert Person.objects.get(pk=person2.pk) == person2


def test_single_query_for_non_paginated_table(settings):
def test_single_query_for_non_paginated_table():
'''
A non-paginated table should not generate a query for each row, but only
one query to count the rows and one to fetch the rows.
one query fetch the rows.
'''
from django.db import connection
settings.DEBUG = True

for i in range(10):
Person.objects.create(first_name='Bob %d' % randint(0, 200), last_name='Builder')

num_queries_before = len(connection.queries)
Person.objects.create(first_name='Bob %d' % i, last_name='Builder')

class PersonTable(tables.Table):
class Meta:
model = Person
fields = ('first_name', 'last_name')
order_by = ('last_name', 'first_name')

table = PersonTable(Person.objects.all())
request = build_request('/')
RequestConfig(request, paginate=False).configure(table)
table.as_html(request)

# print '\n'.join(q['sql'] for q in connection.queries)
assert len(connection.queries) - num_queries_before == 2


def test_issue_361(settings):
settings.DEBUG = True

bob = Person.objects.create(first_name='Bob', last_name='Builder')
eve = Person.objects.create(first_name='Eve', last_name='Dropper')

for i in range(10):
Player.objects.create(person=bob, score=randint(0, 200))
Player.objects.create(person=eve, score=randint(200, 400))
Player.objects.create(person=bob, score=5)
Player.objects.create(person=eve, score=5)

class UserPlayerTable(tables.Table):
class Meta:
model = Player
fields = ('person.name', 'score',)
order_by = ['score', 'person.first_name']
orderable = False

queryset = Player.objects.filter(score=5)

table = UserPlayerTable(queryset)
RequestConfig(request, paginate={'per_page': per_page}).configure(table)
html = table.as_html(request)

# count the number of rows, subtract one for the header
assert (html.count('<tr') - 1) == per_page
with assertNumQueries(1):
table.as_values()
8 changes: 3 additions & 5 deletions tests/test_templatetags.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
# coding: utf-8
from __future__ import unicode_literals

import django_tables2 as tables
import pytest
from django.core.exceptions import ImproperlyConfigured
from django.template import (Context, RequestContext, Template,
TemplateSyntaxError)
from django.utils import six
from django.utils.six.moves.urllib.parse import parse_qs

import django_tables2 as tables
import pytest
from django_tables2.config import RequestConfig

from .app.models import Person, Region
Expand Down Expand Up @@ -187,6 +186,5 @@ class Meta:

Person.objects.create(first_name='John', last_name='Doo')

with assertNumQueries(count=3):
# Person.objects.count()
with assertNumQueries(count=2):
PersonTable(Person.objects.all()).as_html(build_request())

0 comments on commit ab28669

Please sign in to comment.