GOOGLE ADS

domingo, 24 de abril de 2022

¿Cómo guardar los valores de las casillas de verificación en la base de datos de Django desde el panel de administración?

En el panel de administración de Django, todos los campos se guardan en la base de datos, excepto el flagscampo del SubscriberPlanmodelo. Es decir, puedo (des)marcar cualquier bandera e intentar actualizar un registro, pero los estados de las banderas no se guardarán en la base de datos.

Si ejecuto python manage.py shell, importo SubscriberPlan, hago algo como

 plan = SubscriberPlan.objects.all()[0],
plan.flags = "a"
plan.save()

luego, la base de datos se actualizará y la Activebandera se mostrará en el panel de administración, pero, aún así, no será posible actualizarla desde el panel de administración.

Entonces, ¿cómo es posible en Django guardar este tipo de campo en la base de datos desde el panel de administración? Para ser honesto, no entiendo por qué no se guarda de forma predeterminada, mientras que otros campos se guardan. Parece que el panel de administración, por algún motivo, no pasa los valores de la marca de verificación en su formulario.

admin.py

from django.contrib import admin
from django.utils.safestring import mark_safe
class SubscriberPlanFlagsWidget(forms.Widget):
available_flags = (
('a', ('Active')),
('n', ('New')),
('p', ('Popular')),
def render(self, name, value, attrs=None, renderer=None):
html = []
for f in self.available_flags:
html.append('<li><input type="checkbox" id="flag_%(key)s" %(checked)s key="%(key)s"/><label for="flag_%(key)s">%(name)s</label></li>' % {
'key': f[0], 'name': f[1], 'checked': 'checked' if f[0] in value.lower() else ''})
html = '<input type="hidden" name="%s" value="%s"/><ul class="checkbox flags">%s</ul>' % (name, value, ''.join(html))
return mark_safe(html)
class SubscriberPlanAdmin(admin.ModelAdmin):
def formfield_for_dbfield(self, db_field, **kwargs):
if db_field.name == 'flags':
kwargs['widget'] = SubscriberPlanFlagsWidget
return super(SubscriberPlanAdmin, self).formfield_for_dbfield(db_field, **kwargs)

models.py

from django.db import models
class SubscriberPlan(models.Model):
name = models.CharField(max_length=50, verbose_name=("Name"))
price = models.DecimalField(max_digits=15, decimal_places=2,
verbose_name=("Price"))
flags = models.CharField(max_length=30, verbose_name=("Flags"),
default='', blank=True)
def _check_flag(self, name):
return name in self.flags.lower()
def active(self):
return self._check_flag('a')
def new(self):
return self._check_flag('n')
def popular(self):
return self._check_flag('p')


Solución del problema

renderEl método de su widget traduce el flagscampo en casillas de verificación en el formulario, pero cuando se envía el formulario, debe ir en la otra dirección y traducir las casillas de verificación nuevamente a flags. El widget no sabe cómo hacerlo automáticamente. Al mirar el código fuente de django y los documentos, debe anular el value_from_datadictmétodo. Prueba esto:

class SubscriberPlanFlagsWidget(forms.Widget):
...

def value_from_datadict(self, data, files, name):
value = ''
for f in self.available_flags:
if f[1] in data:
value += f[0]
return value

No hay comentarios:

Publicar un comentario

Regla de Firestore para acceder a la generación de subcolección Permisos faltantes o insuficientes

Tengo problemas con las reglas de Firestore para permitir el acceso a algunos recursos en una subcolección. Tengo algunos requests document...