Skip to content

Conversation

nip3o
Copy link
Contributor

@nip3o nip3o commented Apr 13, 2019

Fixed issue https://code.djangoproject.com/ticket/29049

This is a continuation on #9670

@carltongibson
Copy link
Member

Hey @adamchainz. When you have capacity, can I ask you to look at this since you inputted on the original PR. (Thanks!)

Copy link
Member

@adamchainz adamchainz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good, I have some comments on the general direction though

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest:

However, step-argument is not supported in slicing.

changed to:

The step-argument is not supported. For example::

Also a ..versionadded annotation is needed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed this to your suggestion. Added a versionadded, although I'm not sure which line to put it on?

Copy link
Contributor

@auvipy auvipy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! ready for final review.

priyanshsaxena and others added 11 commits May 10, 2019 15:14
F expressions on string-based fields and arrays can now use standard
python slicing-notation. Added a new class SlicableF that handles
identification of slicable fields. Step-argument is not supported.
Added unit-tests and documentation, with an entry in release-notes.
Used a variable 'field_type' to avoid multiple lookups.
Copy link
Contributor

@atombrella atombrella left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some style guides. django.contrib.postgres is also used in the test cases 👍

* ``connection.queries`` now shows ``COPY … TO`` statements on PostgreSQL.

* :class:`~django.db.models.FilePathField` now accepts a callable ``path``.
* Slicing notation added to F expressions over the following field types:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just nitpicking, but please add a blank line.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also move this to 3.1.txt.

normal Python assignment of value to an instance attribute, in fact it's an SQL
construct describing an operation on the database.

For fields that are string-expressions (or ``django.contrib.postgres.fields.ArrayField``), you can use the standard slicing
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrap at 79 chars.

def slice_expression(self, expression, start, length):
if length is None:
return SliceTransform(start, 2147483647, expression)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this blank line is not needed.

first_instance.field = F('field')[:2]
first_instance.save()
first_instance.refresh_from_db()
self.assertSequenceEqual(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could collapse this to one line.

Copy link
Member

@felixxm felixxm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nip3o Thanks for this patch 👍 I left comments.


def slice_expression(self, expression, start, length):
"""Return a slice of an expression, or None if field is not sliceable."""
return None
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Default implementation should raise NotSupportedError, IMO, e.g.

raise NotSupportedError('This field does not support slicing.')

also test for this error is required.

companies = Company.objects.annotate(first_three=F('name')[:3])
self.assertEqual(companies[0].first_three, "Exa")
self.assertEqual(companies[1].first_three, "Foo")
self.assertEqual(companies[2].first_three, "Tes")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use assertSequenceEqual().

third_instance.refresh_from_db()
self.assertSequenceEqual(
third_instance.field, [2, 3]
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use subTest().

@felixxm
Copy link
Member

felixxm commented Jul 3, 2020

Closing due to inactivity.

ngnpope added a commit to ngnpope/django that referenced this pull request Dec 29, 2023
Supersedes PRs django#9670, django#11208, django#14731, and django#16310.

This adds the following changes over the previous PRs:

- Used `None` to omit `end` in `ArrayField.slice_expression()`
- Handled nested slicing, e.g. `F("name")[1:][:5]`
- Simplified `.resolve_expression()`
- Renamed `SliceableF` to `Sliced`
- Clarified some inline comments

Co-authored-by: Priyansh Saxena <[email protected]>
Co-authored-by: Niclas Olofsson <[email protected]>
Co-authored-by: David Smith <[email protected]>
Co-authored-by: Mariusz Felisiak <[email protected]>
Co-authored-by: Abhinav Yadav <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants