Fixed #25320 -- Reverted ManyToManyField.null to False for backwards compatibility.
Thanks Tom Christie for the report and review.
This commit is contained in:
parent
4c30fa905d
commit
064d4b1cb0
|
@ -176,8 +176,16 @@ class RelatedFieldListFilter(FieldListFilter):
|
|||
self.title = self.lookup_title
|
||||
self.empty_value_display = model_admin.get_empty_value_display()
|
||||
|
||||
@property
|
||||
def include_empty_choice(self):
|
||||
"""
|
||||
Return True if a "(None)" choice should be included, which filters
|
||||
out everything except empty relationships.
|
||||
"""
|
||||
return self.field.null or (self.field.is_relation and self.field.many_to_many)
|
||||
|
||||
def has_output(self):
|
||||
if self.field.null:
|
||||
if self.include_empty_choice:
|
||||
extra = 1
|
||||
else:
|
||||
extra = 0
|
||||
|
@ -204,7 +212,7 @@ class RelatedFieldListFilter(FieldListFilter):
|
|||
}, [self.lookup_kwarg_isnull]),
|
||||
'display': val,
|
||||
}
|
||||
if self.field.null:
|
||||
if self.include_empty_choice:
|
||||
yield {
|
||||
'selected': bool(self.lookup_val_isnull),
|
||||
'query_string': cl.get_query_string({
|
||||
|
|
|
@ -2304,8 +2304,6 @@ class ManyToManyField(RelatedField):
|
|||
|
||||
self.db_table = db_table
|
||||
self.swappable = swappable
|
||||
# Many-to-many fields are always nullable.
|
||||
self.null = True
|
||||
|
||||
def check(self, **kwargs):
|
||||
errors = super(ManyToManyField, self).check(**kwargs)
|
||||
|
@ -2552,7 +2550,6 @@ class ManyToManyField(RelatedField):
|
|||
def deconstruct(self):
|
||||
name, path, args, kwargs = super(ManyToManyField, self).deconstruct()
|
||||
# Handle the simpler arguments.
|
||||
del kwargs["null"]
|
||||
if self.db_table is not None:
|
||||
kwargs['db_table'] = self.db_table
|
||||
if self.remote_field.db_constraint is not True:
|
||||
|
|
|
@ -523,6 +523,16 @@ class ListFiltersTests(TestCase):
|
|||
self.assertEqual(choice['selected'], True)
|
||||
self.assertEqual(choice['query_string'], '?books_contributed__id__exact=%d' % self.django_book.pk)
|
||||
|
||||
# With one book, the list filter should appear because there is also a
|
||||
# (None) option.
|
||||
Book.objects.exclude(pk=self.djangonaut_book.pk).delete()
|
||||
filterspec = changelist.get_filters(request)[0]
|
||||
self.assertEqual(len(filterspec), 2)
|
||||
# With no books remaining, no list filters should appear.
|
||||
Book.objects.all().delete()
|
||||
filterspec = changelist.get_filters(request)[0]
|
||||
self.assertEqual(len(filterspec), 0)
|
||||
|
||||
def test_relatedonlyfieldlistfilter_foreignkey(self):
|
||||
modeladmin = BookAdminRelatedOnlyFilter(Book, site)
|
||||
|
||||
|
|
|
@ -216,3 +216,9 @@ class FieldFlagsTests(test.SimpleTestCase):
|
|||
reverse_field = field.remote_field
|
||||
self.assertEqual(field.model, reverse_field.related_model)
|
||||
self.assertEqual(field.related_model, reverse_field.model)
|
||||
|
||||
def test_null(self):
|
||||
# null isn't well defined for a ManyToManyField, but changing it to
|
||||
# True causes backwards compatibility problems (#25320).
|
||||
self.assertFalse(AllFieldsModel._meta.get_field('m2m').null)
|
||||
self.assertTrue(AllFieldsModel._meta.get_field('reverse2').null)
|
||||
|
|
Loading…
Reference in New Issue