es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Django ForeignKey, ocultar opciones de selección al usuario en el menú desplegable.

Tengo modelos estándar de Django con ForeignKey.

Documentos de Django:

“ForeignKey está representado por django.forms.ModelChoiceField, que es un ChoiceField cuyas opciones son un QuerySet de modelo.”

y

“Si el campo del modelo tiene conjuntos de opciones, entonces el widget del campo del formulario se establecerá en Select, con las opciones provenientes de las opciones del campo del modelo.”

Ahora tengo un menú desplegable con opciones.

No quiero un menú desplegable donde el usuario pueda ver las opciones. Quiero un CharField (campo de texto o similar) donde el usuario escriba, pero aún así eso debe ser una de las opciones de la base de datos para ese campo. Debe escribir una entrada válida.

He intentado:

class TransakcijeForm(forms.ModelForm):
model = models.Transakcije
fields = …..
labels = …..
widgets ={'subscriber':forms.TextInput()}

pero recibo el mensaje:

“Elija una opción válida. Esa opción no es una de las opciones disponibles.” (La entrada es correcta y funciona con el menú desplegable)

Esta es mi primera pregunta aquí y lo siento si me equivoco en el formato.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Según la documentación de Django, parece que si se establecen opciones en el campo del modelo, el widget del campo del formulario se establecerá automáticamente en un widget Select con las opciones provenientes de las opciones del campo del modelo. Por lo tanto, si desea permitir al usuario que escriba su propio valor, pero aún limitarlo a ser una de las opciones predefinidas en la base de datos, podría modificar el widget para permitir la entrada del usuario pero aún verificar que el valor esté en la lista de opciones.

    Una forma de lograr esto sería crear un widget personalizado que se extienda del widget Select, pero permita la entrada del usuario. Luego, en su formulario, puede establecer el widget para el campo de suscriptor para que sea el widget personalizado.

    Código de ejemplo para el widget personalizado:

    from django.forms.widgets import Select
    
    class MySelectTextInput(Select):
        input_type = 'text'
    
        def build_attrs(self, base_attrs, extra_attrs=None):
            attrs = super().build_attrs(base_attrs, extra_attrs=extra_attrs)
            attrs['class'] = 'select-text-input'  # Agregar una clase para aplicar estilo más tarde
            return attrs
    
        def value_from_datadict(self, data, files, name):
            value = data.get(name, None)
            if value:
                return value
            return super().value_from_datadict(data, files, name)
    

    En el código de ejemplo anterior, estamos extendiendo desde el widget Select, pero cambiando el tipo de entrada a texto. Esto permitirá al usuario escribir su propio valor. También estamos agregando una clase al widget que podemos estilizar más tarde.

    En el método value_from_datadict, primero estamos verificando si el valor existe en los datos enviados. Si lo hace, devolveremos ese valor (es decir, lo que el usuario escribió). De lo contrario, volveremos al método value_from_datadict de la superclase, que devolverá el valor seleccionado si el usuario eligió en el menú desplegable.

    Código de ejemplo para el formulario:

    class TransakcijeForm(forms.ModelForm):
        subscriber = forms.CharField()
    
        class Meta:
            model = Transakcije
            fields = ...
            labels = ...
    
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.fields['subscriber'].widget = MySelectTextInput(choices=self.fields['subscriber'].choices)
    

    En el formulario anterior, estamos agregando un CharField para el campo de suscriptor. También estamos anulando el widget para el campo de suscriptor para que sea nuestro widget personalizado, pasando las mismas opciones que se habrían utilizado para el menú desplegable.

    Esto debería permitir al usuario escribir su propio valor, pero aún limitarlo a ser una de las opciones en la base de datos.

Comments are closed.