Skip to content

Commit

Permalink
Merge 2cb8a01 into e8cbb50
Browse files Browse the repository at this point in the history
  • Loading branch information
matllubos committed Sep 21, 2020
2 parents e8cbb50 + 2cb8a01 commit a82f680
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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 a82f680

Please sign in to comment.