In the Django admin panel, all fields are saved to the database, except for the flags field of the SubscriberPlan model. That is, I can (un)check any flag and try to thus update a record, but the flag statuses won't be saved to the database.
If I run python manage.py shell, import SubscriberPlan, do something like
plan = SubscriberPlan.objects.all()[0],
plan.flags = "a"
plan.save()
then the database will be updated and the Active flag will be displayed in the Admin panel, but, still, it won't be possible to update it from the Admin panel.
So, how is it possible in Django to save this kind of a field to the database from the Admin panel? To be honest, I don't understand why it's not saved by default, while other fields are saved. It seems that the Admin panel, for some reason, doesn't pass the checkmark values in its form.
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')