1
0
mirror of https://github.com/django/django.git synced 2024-12-22 17:16:24 +00:00

Fixed #32340 -- Improved usability for form fields with specific input patterns.

This commit is contained in:
Ayush khatri 2024-12-20 20:34:40 +05:30
parent f05edb2b43
commit 25a2631d64
5 changed files with 63 additions and 1 deletions

View File

@ -19,6 +19,7 @@ from django.conf import settings
from django.core import validators
from django.core.exceptions import ValidationError
from django.forms.boundfield import BoundField
from django.forms.fields import Field as DjangoField
from django.forms.utils import from_current_timezone, to_current_timezone
from django.forms.widgets import (
FILE_INPUT_CONTRADICTION,
@ -29,6 +30,7 @@ from django.forms.widgets import (
EmailInput,
FileInput,
HiddenInput,
Input,
MultipleHiddenInput,
NullBooleanSelect,
NumberInput,
@ -1408,3 +1410,14 @@ class JSONField(CharField):
return json.dumps(initial, sort_keys=True, cls=self.encoder) != json.dumps(
self.to_python(data), sort_keys=True, cls=self.encoder
)
class CustomField(DjangoField):
def __init__(self, *, widget=None, placeholder=None, **kwargs):
self.placeholder = placeholder
widget = widget or Input()
if self.placeholder:
widget.attrs.setdefault("placeholder", self.placeholder)
super().__init__(widget=widget, **kwargs)

View File

@ -1 +1,3 @@
<input type="{{ widget.type }}" name="{{ widget.name }}"{% if widget.value != None %} value="{{ widget.value|stringformat:'s' }}"{% endif %}{% include "django/forms/widgets/attrs.html" %}>
{% if widget.attrs.placeholder %}placeholder="{{ widget.attrs.placeholder }}" {% endif %}>

View File

@ -1226,3 +1226,25 @@ class SelectDateWidget(Widget):
("{}_{}".format(name, interval) in data)
for interval in ("year", "month", "day")
)
class Input(Widget):
input_type = None # Subclass must define this
def __init__(self, attrs=None, placeholder=None):
self.placeholder = placeholder # Add placeholder attribute
super().__init__(attrs)
def get_context(self, name, value, attrs):
context = super().get_context(name, value, attrs)
if self.placeholder:
attrs = attrs or {}
attrs.setdefault("placeholder", self.placeholder)
context["widget"]["attrs"] = attrs
return context
def render(self, name, value, attrs=None, renderer=None):
attrs = attrs or {}
if self.placeholder:
attrs["placeholder"] = self.placeholder
return super().render(name, value, attrs, renderer)

View File

@ -1627,3 +1627,13 @@ only requirements are that it implement a ``clean()`` method and that its
You can also customize how a field will be accessed by overriding
:meth:`~django.forms.Field.get_bound_field()`.
DateField
---------
Use this field to input dates. The default expected format is ``YYYY-MM-DD``.
For example: ``2024-12-31``.
TimeField
---------
Use this field to input time. The default expected format is ``HH:MM``.
For example: ``14:30``.

View File

@ -1,5 +1,6 @@
from django.contrib.admin.tests import AdminSeleniumTestCase
from django.test import override_settings
from django.forms import CharField, Form, TextInput
from django.test import SimpleTestCase, override_settings
from django.urls import reverse
from ..models import Article
@ -22,3 +23,17 @@ class LiveWidgetTests(AdminSeleniumTestCase):
self.selenium.find_element(By.ID, "submit").click()
article = Article.objects.get(pk=article.pk)
self.assertEqual(article.content, "\r\nTst\r\n")
class WidgetPlaceholderTests(SimpleTestCase):
def test_placeholder_in_input_widget(self):
widget = TextInput(attrs={"placeholder": "Enter text"})
output = widget.render("name", "")
self.assertIn('placeholder="Enter text"', output)
def test_placeholder_in_field(self):
class ExampleForm(Form):
name = CharField(widget=TextInput(attrs={"placeholder": "Your name"}))
form = ExampleForm()
self.assertIn('placeholder="Your name"', str(form["name"]))