Skip to content

Commit

Permalink
Added SmartModel default __str__ method and add ordering to first/las…
Browse files Browse the repository at this point in the history
…t queryset method
  • Loading branch information
Lubos Matl committed Sep 21, 2020
1 parent e8cbb50 commit 2cb8a01
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 3 deletions.
27 changes: 24 additions & 3 deletions chamber/models/__init__.py
Expand Up @@ -264,6 +264,24 @@ def change_and_save(self, update_only_changed_fields=False, **changed_fields):
bulk_change_and_save(self, update_only_changed_fields=update_only_changed_fields, **changed_fields)
return self.filter()

def first(self, *field_names):
"""
Adds possibility to set order fields to default Django first method.
"""
if field_names:
return self.order_by(*field_names).first()
else:
return super().first()

def last(self, *field_names):
"""
Adds possibility to set order fields to default Django last method.
"""
if field_names:
return self.order_by(*field_names).last()
else:
return super().last()


class SmartQuerySet(SmartQuerySetMixin, models.QuerySet):
pass
Expand Down Expand Up @@ -295,6 +313,12 @@ def __init__(self, *args, **kwargs):
self.changed_fields = DynamicChangedFields(self)
self.post_save = Signal(self)

class Meta:
abstract = True

def __str__(self):
return '{} #{}'.format(self._meta.verbose_name, self.pk)

@classmethod
def from_db(cls, db, field_names, values):
new = super().from_db(db, field_names, values)
Expand Down Expand Up @@ -529,9 +553,6 @@ def get_locked_instance(self):

return self.__class__.objects.filter(pk=self.pk).select_for_update().get()

class Meta:
abstract = True


class SmartOptions(Options):

Expand Down
4 changes: 4 additions & 0 deletions docs/models.rst
Expand Up @@ -284,6 +284,10 @@ will assume the custom filters to be there).

Changes selected fields on the selected queryset and saves it and returns changed objects in the queryset. Difference from update is that there is called save method on the instance, but it is slower. If you want to update only changed fields in the database you can use parameter ``update_only_changed_fields`` to achieve it

.. method:: first(**field_names)

Method is only shortcut to ``Model.objects.order_by('field_name').first()``. With this method you can use ``Model.objects.first('field_name')``

.. method:: last(**field_names)

Method is only shortcut to ``Model.objects.order_by('field_name').last()``. With this method you can use ``Model.objects.last('field_name')``
14 changes: 14 additions & 0 deletions example/dj/apps/test_chamber/tests/models/__init__.py
Expand Up @@ -317,3 +317,17 @@ def test_smart_queryset_fast_distinct(self):
assert_equal(qs.count(), 2)
assert_equal(tuple(qs.values_list('pk', flat=True)), (t.pk, t.pk))
assert_equal(qs.fast_distinct().count(), 1)

def test_smart_model_first_and_last_with_order(self):
test3 = TestSmartModel.objects.create(name='3')
test2 = TestSmartModel.objects.create(name='2')
test1 = TestSmartModel.objects.create(name='1')

assert_equal(TestSmartModel.objects.first('id'), test3)
assert_equal(TestSmartModel.objects.last('id'), test1)

assert_equal(TestSmartModel.objects.first('name'), test1)
assert_equal(TestSmartModel.objects.last('name'), test3)

assert_equal(TestSmartModel.objects.filter(name='2').first(), test2)
assert_equal(TestSmartModel.objects.filter(name='2').last(), test2)

0 comments on commit 2cb8a01

Please sign in to comment.