create - python django documentation
¿Mejor widget de administrador de ArrayField? (3)
No tomo crédito por esto ( fuente original ), pero una opción aún más fácil es subclasificar ArrayField
en el modelo y anular el widget de administración predeterminado. Sigue una implementación básica (probada en Django 1.9 y 1.10):
modelos.py
from django import forms
from django.db import models
from django.contrib.postgres.fields import ArrayField
class ChoiceArrayField(ArrayField):
"""
A field that allows us to store an array of choices.
Uses Django''s Postgres ArrayField
and a MultipleChoiceField for its formfield.
"""
def formfield(self, **kwargs):
defaults = {
''form_class'': forms.MultipleChoiceField,
''choices'': self.base_field.choices,
}
defaults.update(kwargs)
# Skip our parent''s formfield implementation completely as we don''t
# care for it.
# pylint:disable=bad-super-call
return super(ArrayField, self).formfield(**defaults)
FUNCTION_CHOICES = (
(''0'', ''Planning''),
(''1'', ''Operation''),
(''2'', ''Reporting''),
)
class FunctionModel(models.Model):
name = models.CharField(max_length=128, unique=True)
function = ChoiceArrayField(
base_field=models.CharField(max_length=256, choices=FUNCTION_CHOICES),
default=list)
¿Hay alguna manera de hacer que el widget de administración de ArrayField permita agregar y eliminar objetos? Parece que, de forma predeterminada, en su lugar se muestra solo un campo de texto y utiliza una separación de coma para sus valores.
Además de ser inconveniente, AFAICT en el caso de que el campo base de la matriz sea un Char / TextField, esto no permite incluir comas en ninguno de los textos de la matriz.
Para OP, o cualquiera que esté buscando, entre estos útiles bits debería estar listo:
django-select2
ofrece una manera de renderizar el ArrayField
usando Select2 . En su documentación, el ejemplo es para ArrayField
:
Para renderizar los valores ya seleccionados:
class ArrayFieldWidget(Select2TagWidget):
def render_options(self, *args, **kwargs):
try:
selected_choices, = args
except ValueError: # Signature contained `choices` prior to Django 1.10
choices, selected_choices = args
output = [''<option></option>'' if not self.is_required and not self.allow_multiple_selected else '''']
selected_choices = {force_text(v) for v in selected_choices.split('','')}
choices = {(v, v) for v in selected_choices}
for option_value, option_label in choices:
output.append(self.render_option(selected_choices, option_value, option_label))
return ''/n''.join(output)
def value_from_datadict(self, data, files, name):
values = super().value_from_datadict(data, files, name)
return ",".join(values)
Para agregar el widget a su formulario:
class MyForm(ModelForm):
class Meta:
fields = [''my_array_field'']
widgets = {
''my_array_field'': ArrayFieldWidget
}