summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHasan Ramezani <hasan.r67@gmail.com>2020-02-02 17:30:34 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2020-02-05 10:27:01 +0100
commitda79ee472d803963dc3ea81ee67767dc06068aac (patch)
tree6c8ad56c7820dc1fc46cea16fc6250b96d111360
parent1d5fb35e6a23c0670f3a128802a1776c8c7deaa8 (diff)
Fixed #26813 -- Prevented empty choice in ModelChoiceField with RadioSelect for fields with blank=False.
-rw-r--r--django/db/models/fields/related.py1
-rw-r--r--django/forms/models.py16
-rw-r--r--tests/model_forms/models.py3
-rw-r--r--tests/model_forms/test_modelchoicefield.py20
-rw-r--r--tests/model_forms/tests.py17
5 files changed, 50 insertions, 7 deletions
diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py
index f269d9e17f..17a08fa931 100644
--- a/django/db/models/fields/related.py
+++ b/django/db/models/fields/related.py
@@ -980,6 +980,7 @@ class ForeignKey(ForeignObject):
'queryset': self.remote_field.model._default_manager.using(using),
'to_field_name': self.remote_field.field_name,
**kwargs,
+ 'blank': self.blank,
})
def db_check(self, connection):
diff --git a/django/forms/models.py b/django/forms/models.py
index dafc11f995..a4d7118cd1 100644
--- a/django/forms/models.py
+++ b/django/forms/models.py
@@ -13,7 +13,7 @@ from django.forms.forms import BaseForm, DeclarativeFieldsMetaclass
from django.forms.formsets import BaseFormSet, formset_factory
from django.forms.utils import ErrorList
from django.forms.widgets import (
- HiddenInput, MultipleHiddenInput, SelectMultiple,
+ HiddenInput, MultipleHiddenInput, RadioSelect, SelectMultiple,
)
from django.utils.text import capfirst, get_text_list
from django.utils.translation import gettext, gettext_lazy as _
@@ -1184,18 +1184,20 @@ class ModelChoiceField(ChoiceField):
def __init__(self, queryset, *, empty_label="---------",
required=True, widget=None, label=None, initial=None,
help_text='', to_field_name=None, limit_choices_to=None,
- **kwargs):
- if required and (initial is not None):
- self.empty_label = None
- else:
- self.empty_label = empty_label
-
+ blank=False, **kwargs):
# Call Field instead of ChoiceField __init__() because we don't need
# ChoiceField.__init__().
Field.__init__(
self, required=required, widget=widget, label=label,
initial=initial, help_text=help_text, **kwargs
)
+ if (
+ (required and initial is not None) or
+ (isinstance(self.widget, RadioSelect) and not blank)
+ ):
+ self.empty_label = None
+ else:
+ self.empty_label = empty_label
self.queryset = queryset
self.limit_choices_to = limit_choices_to # limit the queryset later.
self.to_field_name = to_field_name
diff --git a/tests/model_forms/models.py b/tests/model_forms/models.py
index 5a80243574..05c6d71a4a 100644
--- a/tests/model_forms/models.py
+++ b/tests/model_forms/models.py
@@ -393,6 +393,9 @@ class Character(models.Model):
username = models.CharField(max_length=100)
last_action = models.DateTimeField()
+ def __str__(self):
+ return self.username
+
class StumpJoke(models.Model):
most_recently_fooled = models.ForeignKey(
diff --git a/tests/model_forms/test_modelchoicefield.py b/tests/model_forms/test_modelchoicefield.py
index 4a2ef30b90..1d4b9f9e70 100644
--- a/tests/model_forms/test_modelchoicefield.py
+++ b/tests/model_forms/test_modelchoicefield.py
@@ -139,6 +139,26 @@ class ModelChoiceFieldTests(TestCase):
Category.objects.all().delete()
self.assertIs(bool(f.choices), True)
+ def test_choices_radio_blank(self):
+ choices = [
+ (self.c1.pk, 'Entertainment'),
+ (self.c2.pk, 'A test'),
+ (self.c3.pk, 'Third'),
+ ]
+ categories = Category.objects.all()
+ for widget in [forms.RadioSelect, forms.RadioSelect()]:
+ for blank in [True, False]:
+ with self.subTest(widget=widget, blank=blank):
+ f = forms.ModelChoiceField(
+ categories,
+ widget=widget,
+ blank=blank,
+ )
+ self.assertEqual(
+ list(f.choices),
+ [('', '---------')] + choices if blank else choices,
+ )
+
def test_deepcopies_widget(self):
class ModelChoiceForm(forms.Form):
category = forms.ModelChoiceField(Category.objects.all())
diff --git a/tests/model_forms/tests.py b/tests/model_forms/tests.py
index a4e1ee1183..0caf6e9bad 100644
--- a/tests/model_forms/tests.py
+++ b/tests/model_forms/tests.py
@@ -273,6 +273,23 @@ class ModelFormBaseTest(TestCase):
(writer.pk, 'Joe Doe'),
])
+ def test_non_blank_foreign_key_with_radio(self):
+ class AwardForm(forms.ModelForm):
+ class Meta:
+ model = Award
+ fields = ['character']
+ widgets = {'character': forms.RadioSelect()}
+
+ character = Character.objects.create(
+ username='user',
+ last_action=datetime.datetime.today(),
+ )
+ form = AwardForm()
+ self.assertEqual(
+ list(form.fields['character'].choices),
+ [(character.pk, 'user')],
+ )
+
def test_save_blank_false_with_required_false(self):
"""
A ModelForm with a model with a field set to blank=False and the form