[Django] 创建了一个将电话号码分为三部分的表单
我想在Django中创建一个电话号码以三个数字分隔的表单!
↓
哎呀,Django的标准库里没有提供这个功能吗?
太麻烦了,要自己编写这个功能。
↓
求助,GPT大神!!!
取胜
from hogeapp.custom_forms import PhoneNumberField
class HogeForm(forms.Form):
phone_number = PhoneNumberField()
<div>
<label for="phone-number">{{ form.phone_number.label }}</label>
{{ form.phone_number }}
<div class="text-danger">
{{ form.phone_number.errors }}
</div>
</div>
import re
from django import forms
from django.core.exceptions import ValidationError
from django.core.validators import MinLengthValidator, MaxLengthValidator
from django.forms import MultiValueField, MultiWidget
from django.forms.fields import CharField
from django.forms.widgets import TextInput
from django.utils.safestring import mark_safe
def validate_integer(value):
if not re.match("^[0-9]+$", value):
raise ValidationError('入力は整数でなければなりません。')
class PhoneNumberWidget(MultiWidget):
def __init__(self, attrs=None):
_attrs = attrs if attrs else {}
_attrs.update({"class": "form-control"})
widgets = [TextInput(attrs=_attrs), TextInput(attrs=_attrs), TextInput(attrs=_attrs)]
super().__init__(widgets, attrs)
def decompress(self, value):
if value:
return value.split('-')
return ['', '', '']
def render(self, name, value, attrs=None, renderer=None):
rendered_widgets = []
for index, widget_data in enumerate(self.get_context(name, value, attrs)['widget']['subwidgets']):
widget_instance = self.widgets[index]
rendered_widgets.append(widget_instance.render(name=widget_data['name'], value=widget_data['value'], attrs=widget_data['attrs']))
return mark_safe(f"<div style='display:flex; align-items: center;'>{rendered_widgets[0]}<span style='margin: 0 5px;'> - </span>{rendered_widgets[1]}<span style='margin: 0 5px;'> - </span>{rendered_widgets[2]}</div>")
class PhoneNumberField(MultiValueField):
widget = PhoneNumberWidget
def __init__(self, *args, **kwargs):
fields = (
CharField(validators=[validate_integer,
MinLengthValidator(2, '電話番号1(市外局番)は最低2桁です。'),
MaxLengthValidator(3, '電話番号1(市外局番)は最大3桁です。')]),
CharField(validators=[validate_integer,
MinLengthValidator(1, '電話番号2(市内局番)は最低1桁です。'),
MaxLengthValidator(4, '電話番号2(市内局番)は最大4桁です。')]),
CharField(validators=[validate_integer,
MinLengthValidator(4, '電話番号3(加入者番号)は4桁です。'),
MaxLengthValidator(4, '電話番号3(加入者番号)は4桁です。')]),
)
super().__init__(fields, *args, **kwargs)
def compress(self, data_list):
if data_list:
return '-'.join(data_list)
return ''
请注意
-
- コピペして使ってバグっても責任を負いかねます?♂
- bootstrap5を使って開発している都合上、フォームにform-controlクラスをいれています
以下内容
将电话号码表单分成三部分的规范本身是否是一种反例呢?