Fixed #33084 -- Removed incorrect system check for ManyToManyField with limit_choices_to.
This commit is contained in:
parent
46c8df640c
commit
0a28b42b15
|
@ -1247,17 +1247,6 @@ class ManyToManyField(RelatedField):
|
||||||
id='fields.W341',
|
id='fields.W341',
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
if (self.remote_field.limit_choices_to and self.remote_field.through and
|
|
||||||
not self.remote_field.through._meta.auto_created):
|
|
||||||
warnings.append(
|
|
||||||
checks.Warning(
|
|
||||||
'limit_choices_to has no effect on ManyToManyField '
|
|
||||||
'with a through model.',
|
|
||||||
obj=self,
|
|
||||||
id='fields.W343',
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if self.remote_field.symmetrical and self._related_name:
|
if self.remote_field.symmetrical and self._related_name:
|
||||||
warnings.append(
|
warnings.append(
|
||||||
checks.Warning(
|
checks.Warning(
|
||||||
|
|
|
@ -310,7 +310,7 @@ Related fields
|
||||||
* **fields.W342**: Setting ``unique=True`` on a ``ForeignKey`` has the same
|
* **fields.W342**: Setting ``unique=True`` on a ``ForeignKey`` has the same
|
||||||
effect as using a ``OneToOneField``.
|
effect as using a ``OneToOneField``.
|
||||||
* **fields.W343**: ``limit_choices_to`` has no effect on ``ManyToManyField``
|
* **fields.W343**: ``limit_choices_to`` has no effect on ``ManyToManyField``
|
||||||
with a ``through`` model.
|
with a ``through`` model. *This check appeared before Django 4.0.*
|
||||||
* **fields.W344**: The field's intermediary table ``<table name>`` clashes with
|
* **fields.W344**: The field's intermediary table ``<table name>`` clashes with
|
||||||
the table name of ``<model>``/``<model>.<field name>``.
|
the table name of ``<model>``/``<model>.<field name>``.
|
||||||
* **fields.W345**: ``related_name`` has no effect on ``ManyToManyField`` with a
|
* **fields.W345**: ``related_name`` has no effect on ``ManyToManyField`` with a
|
||||||
|
|
|
@ -1810,10 +1810,6 @@ that control how the relationship functions.
|
||||||
|
|
||||||
Same as :attr:`ForeignKey.limit_choices_to`.
|
Same as :attr:`ForeignKey.limit_choices_to`.
|
||||||
|
|
||||||
``limit_choices_to`` has no effect when used on a ``ManyToManyField`` with a
|
|
||||||
custom intermediate table specified using the
|
|
||||||
:attr:`~ManyToManyField.through` parameter.
|
|
||||||
|
|
||||||
.. attribute:: ManyToManyField.symmetrical
|
.. attribute:: ManyToManyField.symmetrical
|
||||||
|
|
||||||
Only used in the definition of ManyToManyFields on self. Consider the
|
Only used in the definition of ManyToManyFields on self. Consider the
|
||||||
|
|
|
@ -81,32 +81,12 @@ class RelativeFieldTests(SimpleTestCase):
|
||||||
field = Model._meta.get_field('m2m')
|
field = Model._meta.get_field('m2m')
|
||||||
self.assertEqual(field.check(from_model=Model), [])
|
self.assertEqual(field.check(from_model=Model), [])
|
||||||
|
|
||||||
def test_many_to_many_with_limit_choices_auto_created_no_warning(self):
|
|
||||||
class Model(models.Model):
|
|
||||||
name = models.CharField(max_length=20)
|
|
||||||
|
|
||||||
class ModelM2M(models.Model):
|
|
||||||
m2m = models.ManyToManyField(Model, limit_choices_to={'name': 'test_name'})
|
|
||||||
|
|
||||||
self.assertEqual(ModelM2M.check(), [])
|
|
||||||
|
|
||||||
def test_many_to_many_with_useless_options(self):
|
def test_many_to_many_with_useless_options(self):
|
||||||
class Model(models.Model):
|
class Model(models.Model):
|
||||||
name = models.CharField(max_length=20)
|
name = models.CharField(max_length=20)
|
||||||
|
|
||||||
class ModelM2M(models.Model):
|
class ModelM2M(models.Model):
|
||||||
m2m = models.ManyToManyField(
|
m2m = models.ManyToManyField(Model, null=True, validators=[lambda x: x])
|
||||||
Model,
|
|
||||||
null=True,
|
|
||||||
validators=[lambda x: x],
|
|
||||||
limit_choices_to={'name': 'test_name'},
|
|
||||||
through='ThroughModel',
|
|
||||||
through_fields=('modelm2m', 'model'),
|
|
||||||
)
|
|
||||||
|
|
||||||
class ThroughModel(models.Model):
|
|
||||||
model = models.ForeignKey('Model', models.CASCADE)
|
|
||||||
modelm2m = models.ForeignKey('ModelM2M', models.CASCADE)
|
|
||||||
|
|
||||||
field = ModelM2M._meta.get_field('m2m')
|
field = ModelM2M._meta.get_field('m2m')
|
||||||
self.assertEqual(ModelM2M.check(), [
|
self.assertEqual(ModelM2M.check(), [
|
||||||
|
@ -120,12 +100,6 @@ class RelativeFieldTests(SimpleTestCase):
|
||||||
obj=field,
|
obj=field,
|
||||||
id='fields.W341',
|
id='fields.W341',
|
||||||
),
|
),
|
||||||
DjangoWarning(
|
|
||||||
'limit_choices_to has no effect on ManyToManyField '
|
|
||||||
'with a through model.',
|
|
||||||
obj=field,
|
|
||||||
id='fields.W343',
|
|
||||||
),
|
|
||||||
])
|
])
|
||||||
|
|
||||||
def test_many_to_many_with_useless_related_name(self):
|
def test_many_to_many_with_useless_related_name(self):
|
||||||
|
|
|
@ -480,3 +480,20 @@ class NullableUniqueCharFieldModel(models.Model):
|
||||||
email = models.EmailField(blank=True, null=True)
|
email = models.EmailField(blank=True, null=True)
|
||||||
slug = models.SlugField(blank=True, null=True)
|
slug = models.SlugField(blank=True, null=True)
|
||||||
url = models.URLField(blank=True, null=True)
|
url = models.URLField(blank=True, null=True)
|
||||||
|
|
||||||
|
|
||||||
|
class Number(models.Model):
|
||||||
|
value = models.IntegerField()
|
||||||
|
|
||||||
|
|
||||||
|
class NumbersToDice(models.Model):
|
||||||
|
number = models.ForeignKey('Number', on_delete=models.CASCADE)
|
||||||
|
die = models.ForeignKey('Dice', on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
|
||||||
|
class Dice(models.Model):
|
||||||
|
numbers = models.ManyToManyField(
|
||||||
|
Number,
|
||||||
|
through=NumbersToDice,
|
||||||
|
limit_choices_to=models.Q(value__gte=1),
|
||||||
|
)
|
||||||
|
|
|
@ -21,10 +21,10 @@ from django.test.utils import isolate_apps
|
||||||
from .models import (
|
from .models import (
|
||||||
Article, ArticleStatus, Author, Author1, Award, BetterWriter, BigInt, Book,
|
Article, ArticleStatus, Author, Author1, Award, BetterWriter, BigInt, Book,
|
||||||
Category, Character, Colour, ColourfulItem, CustomErrorMessage, CustomFF,
|
Category, Character, Colour, ColourfulItem, CustomErrorMessage, CustomFF,
|
||||||
CustomFieldForExclusionModel, DateTimePost, DerivedBook, DerivedPost,
|
CustomFieldForExclusionModel, DateTimePost, DerivedBook, DerivedPost, Dice,
|
||||||
Document, ExplicitPK, FilePathModel, FlexibleDatePost, Homepage,
|
Document, ExplicitPK, FilePathModel, FlexibleDatePost, Homepage,
|
||||||
ImprovedArticle, ImprovedArticleWithParentLink, Inventory,
|
ImprovedArticle, ImprovedArticleWithParentLink, Inventory,
|
||||||
NullableUniqueCharFieldModel, Person, Photo, Post, Price, Product,
|
NullableUniqueCharFieldModel, Number, Person, Photo, Post, Price, Product,
|
||||||
Publication, PublicationDefaults, StrictAssignmentAll,
|
Publication, PublicationDefaults, StrictAssignmentAll,
|
||||||
StrictAssignmentFieldSpecific, Student, StumpJoke, TextFile, Triple,
|
StrictAssignmentFieldSpecific, Student, StumpJoke, TextFile, Triple,
|
||||||
Writer, WriterProfile, test_images,
|
Writer, WriterProfile, test_images,
|
||||||
|
@ -2896,6 +2896,19 @@ class LimitChoicesToTests(TestCase):
|
||||||
[self.marley, self.threepwood],
|
[self.marley, self.threepwood],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_limit_choices_to_m2m_through(self):
|
||||||
|
class DiceForm(forms.ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = Dice
|
||||||
|
fields = ['numbers']
|
||||||
|
|
||||||
|
Number.objects.create(value=0)
|
||||||
|
n1 = Number.objects.create(value=1)
|
||||||
|
n2 = Number.objects.create(value=2)
|
||||||
|
|
||||||
|
form = DiceForm()
|
||||||
|
self.assertCountEqual(form.fields['numbers'].queryset, [n1, n2])
|
||||||
|
|
||||||
|
|
||||||
class FormFieldCallbackTests(SimpleTestCase):
|
class FormFieldCallbackTests(SimpleTestCase):
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue