Skip to content

Commit

Permalink
use pk instead of QuerySetIsh
Browse files Browse the repository at this point in the history
  • Loading branch information
Alex Riina committed Nov 17, 2015
1 parent 9612bcc commit de39ae1
Show file tree
Hide file tree
Showing 2 changed files with 1 addition and 74 deletions.
43 changes: 0 additions & 43 deletions django_object_actions/tests/test_utils.py
@@ -1,12 +1,9 @@
from django.db.models.query import QuerySet
from django.test import TestCase
from django.utils.unittest import expectedFailure

from example_project.polls.models import Poll

from ..utils import (
BaseDjangoObjectActions,
QuerySetIsh,
takes_instance_or_queryset,
)

Expand Down Expand Up @@ -66,43 +63,6 @@ def test_get_djoa_button_attrs_custom_attrs_get_partitioned(self):
self.assertEqual(custom['nonstandard'], 'wombat')


class QuerySetIshTest(TestCase):
fixtures = ['sample_data']

def setUp(self):
# WISHLIST don't depend on fixture
self.obj = Poll.objects.get(pk=1)

def test_can_turn_object_into_queryset(self):
qs = QuerySetIsh(self.obj)
self.assertEqual(qs.count(), 1)
self.assertEqual(qs.get(), self.obj)
self.assertEqual(qs.order_by('foo').get(), self.obj)
self.assertEqual(qs.all().get(), self.obj)
self.assertEqual(qs.filter().get(), self.obj)
self.assertEqual(qs.latest('bar'), self.obj)

def test_queryset_supports_delete(self):
qs = QuerySetIsh(self.obj)
qs.delete()
with self.assertRaises(Poll.DoesNotExist):
Poll.objects.get(pk=1)

@expectedFailure
def test_queryset_supports_filter(self):
# yeah, we don't actually support doing this, but it would be nice.
qs = QuerySetIsh(self.obj)
with self.assertRaises(Poll.DoesNotExist):
# this should be empty because the question is just `"hi"`
qs.filter(question='abra cadabra').get()

def test_queryset_supports_update(self):
qs = QuerySetIsh(self.obj)
qs.update(question='mooo')
self.assertEqual(Poll.objects.get(pk=1).question, 'mooo')
self.assertEqual(Poll.objects.get(pk=2).question, 'wut?')


class DecoratorTest(TestCase):
fixtures = ['sample_data']

Expand All @@ -129,17 +89,14 @@ def myfunc(foo, bar, queryset):

# passing in an instance yields a queryset (using positional args)
queryset = myfunc(None, None, self.obj)
self.assertIsInstance(queryset, QuerySet)
# the resulting queryset only has one item and it's self.obj
self.assertEqual(queryset.get(), self.obj)

# passing in a queryset yields the same queryset
queryset = myfunc(None, None, self.queryset)
self.assertIsInstance(queryset, QuerySet)
self.assertEqual(queryset, self.queryset)

# passing in an instance yields a queryset (using keyword args)
queryset = myfunc(None, None, queryset=self.obj)
self.assertIsInstance(queryset, QuerySet)
# the resulting queryset only has one item and it's self.obj
self.assertEqual(queryset.get(), self.obj)
32 changes: 1 addition & 31 deletions django_object_actions/utils.py
Expand Up @@ -136,43 +136,13 @@ def message_user(self, request, message):
messages.info(request, message)


class QuerySetIsh(QuerySet):
"""
Takes an instance and mimics it coming from a QuerySet.
This is a hack to support the `takes_instance_or_queryset` decorator so
that you can re-use functions written for standard Django admin actions and
use them for Object Tools too.
"""
def __init__(self, instance=None, *args, **kwargs):
try:
model = instance._meta.model
except AttributeError:
# Django 1.5 does this instead, getting the model may be overkill
# we may be able to throw away all this logic
model = instance._meta.concrete_model
self._doa_instance = instance
super(QuerySetIsh, self).__init__(model, *args, **kwargs)
self._result_cache = [instance]

def _clone(self, *args, **kwargs):
# don't clone me, bro
return self

def get(self, *args, **kwargs):
# Starting in Django 1.7, `QuerySet.get` started slicing to
# `MAX_GET_RESULTS`, so to avoid messing with `__getslice__`, override
# `.get`.
return self._doa_instance


def takes_instance_or_queryset(func):
"""Decorator that makes standard Django admin actions compatible."""
@wraps(func)
def decorated_function(self, request, queryset):
# func follows the prototype documented at:
# https://docs.djangoproject.com/en/dev/ref/contrib/admin/actions/#writing-action-functions
if not isinstance(queryset, QuerySet):
queryset = QuerySetIsh(queryset)
queryset = queryset._meta.model.objects.filter(pk=queryset.pk)
return func(self, request, queryset)
return decorated_function

0 comments on commit de39ae1

Please sign in to comment.