what personalizados meet formularios fields develop avanzados html django forms html5

personalizados - ¿Cómo obtengo los formularios Django para mostrar el atributo html requerido?



meet django (6)

Combinando las respuestas de Daniel y Daniel, normalmente uso esta combinación para mis formularios:

from django.contrib.admin.widgets import AdminFileWidget from django.forms.widgets import HiddenInput, FileInput class HTML5RequiredMixin(object): def __init__(self, *args, **kwargs): super(HTML5RequiredMixin, self).__init__(*args, **kwargs) for field in self.fields: if (self.fields[field].required and type(self.fields[field].widget) not in (AdminFileWidget, HiddenInput, FileInput) and ''__prefix__'' not in self.fields[field].widget.attrs): self.fields[field].widget.attrs[''required''] = ''required'' if self.fields[field].label: self.fields[field].label += '' *''

Entonces, cuando tengo que crear una nueva forma o modelo, solo uso:

class NewForm(HTML5RequiredMixin, forms.Form): ...

Tengo este campo de formulario:

email = forms.EmailField( required=True, max_length=100, )

Tiene el atributo requerido, pero en el html no está agregando el atributo html required . De hecho, ni siquiera utiliza el email como tipo de campo, usa text ... aunque parece que max_length está bien.

Real:

<input id="id_email" type="text" name="email" maxlength="100">

Esperado:

<input id="id_email" type="email" name="email" maxlength="100" required="true">

¿Cómo puedo hacer que Django use los atributos correctos en formularios html?


Como se ha dado cuenta, establecer su atributo Campo requerido en True es solo para la validación del servidor, tal como se explica en la documentación de Django .

Lo que realmente desea es agregar un atributo requerido al Widget del campo:

email.widget.attrs["required"] = "required"

Pero si realmente desea escribir código DRY elegante, debe crear una clase de formulario base que busque dinámicamente todos los campos requeridos y modifique el atributo requerido de su widget para usted (puede nombrarlo como desee, pero "BaseForm" parece apropiado ):

from django.forms import ModelForm class BaseForm(ModelForm): def __init__(self, *args, **kwargs): super(BaseForm, self).__init__(*args, **kwargs) for bound_field in self: if hasattr(bound_field, "field") and bound_field.field.required: bound_field.field.widget.attrs["required"] = "required"

Y luego haz que todos tus objetos de Forma desciendan de ella:

class UserForm(BaseForm): class Meta: model = User fields = [] first_name = forms.CharField(required=True) last_name = forms.CharField(required=True) email = forms.EmailField(required=True, max_length=100)


Desde Django 1.10, esto está incorporado.

De las notas de publicación :

Los campos de formulario requeridos ahora tienen el atributo HTML requerido. Establezca el nuevo atributo Form.use_required_attribute en False para deshabilitarlo.


Los elementos del formulario Django se escriben en contra de <input /> tal como existe en HTML 4, donde type="text" era la opción correcta para las direcciones de correo electrónico. Tampoco había required="true" .

Si desea atributos HTML personalizados, necesita el argumento de la palabra clave attrs para el widget . Se vería algo como esto:

email = forms.EmailField( max_length=100, required=True, widget=forms.TextInput(attrs={ ''required'': ''true'' }), )

Puedes consultar más documentación sobre widgets here . La discusión de attrs está cerca de la parte inferior de esa página.

Con respecto a type="email" , podría enviarlo a su diccionario de attrs y Django anulará de manera inteligente su valor predeterminado. Si ese no es el resultado que obtiene, entonces su ruta es a los forms.TextInput subclase. forms.TextInput y luego lo pasa al argumento de la palabra clave del widget .


Monkeypatching Widget es tu mejor apuesta:

from django.forms.widgets import Widget from django.contrib.admin.widgets import AdminFileWidget from django.forms import HiddenInput, FileInput old_build_attrs = Widget.build_attrs def build_attrs(self, extra_attrs=None, **kwargs): attrs = old_build_attrs(self, extra_attrs, **kwargs) # if required, and it''s not a file widget since those can have files # attached without seeming filled-in to the browser, and skip hidden "mock" # fileds created for StackedInline and TabbedInline admin stuff if (self.is_required and type(self) not in (AdminFileWidget, HiddenInput, FileInput) and "__prefix__" not in attrs.get("name", "")): attrs[''required''] = ''required'' return attrs Widget.build_attrs = build_attrs


También está la solución de solo plantilla que utiliza un filtro. Recomiendo django-widget-tweaks :

{% load widget_tweaks %} {{ form.email|attr:''required:true'' }}

Eso fue fácil.