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',
|
||||
)
|
||||
)
|
||||
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:
|
||||
warnings.append(
|
||||
checks.Warning(
|
||||
|
|
|
@ -310,7 +310,7 @@ Related fields
|
|||
* **fields.W342**: Setting ``unique=True`` on a ``ForeignKey`` has the same
|
||||
effect as using a ``OneToOneField``.
|
||||
* **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
|
||||
the table name of ``<model>``/``<model>.<field name>``.
|
||||
* **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`.
|
||||
|
||||
``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
|
||||
|
||||
Only used in the definition of ManyToManyFields on self. Consider the
|
||||
|
|
|
@ -81,32 +81,12 @@ class RelativeFieldTests(SimpleTestCase):
|
|||
field = Model._meta.get_field('m2m')
|
||||
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):
|
||||
class Model(models.Model):
|
||||
name = models.CharField(max_length=20)
|
||||
|
||||
class ModelM2M(models.Model):
|
||||
m2m = models.ManyToManyField(
|
||||
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)
|
||||
m2m = models.ManyToManyField(Model, null=True, validators=[lambda x: x])
|
||||
|
||||
field = ModelM2M._meta.get_field('m2m')
|
||||
self.assertEqual(ModelM2M.check(), [
|
||||
|
@ -120,12 +100,6 @@ class RelativeFieldTests(SimpleTestCase):
|
|||
obj=field,
|
||||
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):
|
||||
|
|
|
@ -480,3 +480,20 @@ class NullableUniqueCharFieldModel(models.Model):
|
|||
email = models.EmailField(blank=True, null=True)
|
||||
slug = models.SlugField(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 (
|
||||
Article, ArticleStatus, Author, Author1, Award, BetterWriter, BigInt, Book,
|
||||
Category, Character, Colour, ColourfulItem, CustomErrorMessage, CustomFF,
|
||||
CustomFieldForExclusionModel, DateTimePost, DerivedBook, DerivedPost,
|
||||
CustomFieldForExclusionModel, DateTimePost, DerivedBook, DerivedPost, Dice,
|
||||
Document, ExplicitPK, FilePathModel, FlexibleDatePost, Homepage,
|
||||
ImprovedArticle, ImprovedArticleWithParentLink, Inventory,
|
||||
NullableUniqueCharFieldModel, Person, Photo, Post, Price, Product,
|
||||
NullableUniqueCharFieldModel, Number, Person, Photo, Post, Price, Product,
|
||||
Publication, PublicationDefaults, StrictAssignmentAll,
|
||||
StrictAssignmentFieldSpecific, Student, StumpJoke, TextFile, Triple,
|
||||
Writer, WriterProfile, test_images,
|
||||
|
@ -2896,6 +2896,19 @@ class LimitChoicesToTests(TestCase):
|
|||
[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):
|
||||
|
||||
|
|
Loading…
Reference in New Issue