Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refs #28458 -- Added validate_choices to ModelMultipleChoiceField. #14033

Closed
wants to merge 1 commit into from

Conversation

gasparb16
Copy link

I fixed the review findings from: #7181

Co-authored-by: blueyed github@thequod.de

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.

@gasparb16 Thanks for this patch 👍

@@ -1357,6 +1357,15 @@ generating choices. See :ref:`iterating-relationship-choices` for details.

.. _iterating-relationship-choices:

.. method:: ModelMultipleChoiceField.validate_choices(queryset, field_name, selected_choices)
Copy link
Member

Choose a reason for hiding this comment

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

This should be above the .. _iterating-relationship-choices:. Also versionadded:: 4.0 annotation and release notes are missing, see #7181 (comment).

Copy link
Author

Choose a reason for hiding this comment

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

I was not sure what the new use-case would be regarding the super() call, I would gladly accept some help with this.

Copy link
Member

Choose a reason for hiding this comment

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

We should have a valid use case if we want to add a new hook 🤔 It can be used to avoid a queryset evaluation, but I'm not sure it's enough to justify adding it. It's really niche and was more of a workaround than a real need (see ticket-27148). I'm going to say wontfix unless there's a more legitimate use-case.

Copy link
Author

Choose a reason for hiding this comment

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

Yeah I understand, I just wanted to fix the issues in the PR and code some and if it is needed merge it. But I am fine with a wontfix that closes the ticket as well.


with self.assertNumQueries(1):
field = CustomModelMultipleChoiceField(Category.objects.all())
with self.assertRaises(ValidationError) as exc:
Copy link
Member

Choose a reason for hiding this comment

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

Use assertRaisesMessage().

def test_model_multiple_choice_field_validate_choices(self):
with self.assertNumQueries(1):
field = forms.ModelMultipleChoiceField(Category.objects.all())
with self.assertRaises(ValidationError) as exc:
Copy link
Member

Choose a reason for hiding this comment

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

Use assertRaisesMessage().

Copy link
Author

Choose a reason for hiding this comment

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

I am not sure if we can use this, because I would like to assert to the exc.exception.params not the message

Copy link
Member

Choose a reason for hiding this comment

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

True, exc -> cm.

class CustomModelMultipleChoiceField(forms.ModelMultipleChoiceField, TestCase):
def validate_choices(self, queryset, field_name, selected_choices):
self.assertIsInstance(queryset, models.QuerySet)
self.assertQuerysetEqual(queryset.order_by('id'), [1], lambda a: a.id)
Copy link
Member

Choose a reason for hiding this comment

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

We cannot make serial pk assumption:

diff --git a/tests/model_forms/tests.py b/tests/model_forms/tests.py
index 8b54611010..ea68a105d6 100644
--- a/tests/model_forms/tests.py
+++ b/tests/model_forms/tests.py
@@ -1765,10 +1765,12 @@ class ModelMultipleChoiceFieldTests(TestCase):
             f.clean([c6.id])
 
     def test_model_multiple_choice_field_validate_choices_called_properly(self):
+        c1 = self.c1
+
         class CustomModelMultipleChoiceField(forms.ModelMultipleChoiceField, TestCase):
             def validate_choices(self, queryset, field_name, selected_choices):
                 self.assertIsInstance(queryset, models.QuerySet)
-                self.assertQuerysetEqual(queryset.order_by('id'), [1], lambda a: a.id)
+                self.assertSequenceEqual(queryset, [c1])
                 self.assertIsInstance(field_name, str)
                 self.assertEqual(field_name, 'pk')
                 self.assertIsInstance(selected_choices, frozenset)

@@ -1357,6 +1357,15 @@ generating choices. See :ref:`iterating-relationship-choices` for details.

.. _iterating-relationship-choices:

.. method:: ModelMultipleChoiceField.validate_choices(queryset, field_name, selected_choices)

``validate_choices`` gets called with the filtered queryset (``queryset``), the name
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
``validate_choices`` gets called with the filtered queryset (``queryset``), the name
``validate_choices`` gets called with the filtered ``queryset``, the name

.. method:: ModelMultipleChoiceField.validate_choices(queryset, field_name, selected_choices)

``validate_choices`` gets called with the filtered queryset (``queryset``), the name
of the field, and the list of selected values. It should return the queryset.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
of the field, and the list of selected values. It should return the queryset.
of the field, and the list of selected values. It should return the queryset.

of the field, and the list of selected values. It should return the queryset.

The default implementation raises a ``ValidationError`` in case any of the
``values`` is not in the list of attribute lookups of ``field_name`` in ``qs``
Copy link
Member

Choose a reason for hiding this comment

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

`

Suggested change
``values`` is not in the list of attribute lookups of ``field_name`` in ``qs``
``values`` is not in the list of attribute lookups of ``field_name`` in ``queryset``

Co-authored-by: blueyed <github@thequod.de>
@felixxm
Copy link
Member

felixxm commented Mar 2, 2021

@gasparb16 Thanks for your effort! 👍

Closing per ticket.

@felixxm felixxm closed this Mar 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants