Как сохранить флаги в базу данных Django из панели администратора?
В админпанели Django все поля сохраняются в БД, кроме поля flags модели SubscriberPlan. То есть я могу (не)проверить любой флаг и попытаться таким образом обновить запись, но статусы флагов не будут сохранены в базе данных.
Если я запускаю python manage.py shell, импортирую SubscriberPlan, делаю что-то вроде
plan = SubscriberPlan.objects.all()[0],
plan.flags = "a"
plan.save()
тогда база данных будет обновлена и флаг Active будет отображаться в панели администратора, но, тем не менее, обновить ее из панели администратора будет невозможно.
Итак, как в Django можно сохранить такое поле в базу данных из панели администратора? Честно говоря, я не понимаю, почему оно не сохраняется по умолчанию, в то время как другие поля сохраняются . Похоже, что Админ-панель по какой-то причине не передает значения галочки в своей форме.
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')
Посмотрев исходный код и документы, я думаю, что value_from_datadict - это то, что вам нужно. Попробуйте это:
class SubscriberPlanFlagsWidget(forms.Widget):
# Your existing code
...
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