我创建了一个字段来保存工作日,在类似的模型(models.py
)中使用:
from myfields import *
from django.db import models
class MyModel(models.Model):
weekdays = WeekdayField()
我存储表单声明的文件是myfields.py
,并且是这个:
from django.db import models
from django import forms
class Weekdays(object):
CHOICES = (
(1, "Monday"),
(2, "Tuesday"),
(4, "Wednesday"),
(8, "Thursday"),
(16, "Friday"),
(32, "Saturday"),
(64, "Sunday"),
)
MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY = [2**i for i in range(0,7)]
del i
def __init__(self, value=0):
self.raw = value
def __add__(self, other):
return Weekdays(self.raw | other)
def __sub__(self, other):
return Weekdays(self.raw & (-1 ^ other))
def __unicode__(self):
ret = []
for ele in Weekdays.CHOICES:
if (self.raw & ele[0]) >> ele[0] == 1:
ret.append(ele[1])
return ",".join(ret)
def __iter__(self):
ret = []
for ele in Weekdays.CHOICES:
if (self.raw & ele[0]) >> ele[0] == 1:
ret.append(ele)
return iter(ret)
def __len__(self):
i = 0
for n in range(7):
if (self.raw & n) >> n == 1:
i += 1
return i
class WeekdayField(models.Field):
description = "Multiple select of weekdays"
__metaclass__ = models.SubfieldBase
def __init__(self, *args, **kwargs):
kwargs['max_length'] = 3
super(WeekdayField, self).__init__(*args, **kwargs)
def to_python(self, value):
if isinstance(value, int):
return [ wd for wd in Weekdays(value) ]
if isinstance(value, Weekdays):
return value
if isinstance(value, list): #list of weekstay
wd = Weekdays()
for val in value:
wd += int(val)
return wd
# PY to DB
def get_prep_value(self, value):
return value.raw
def formfield(self, **kwargs):
defaults = {'form_class': WeekdayFormField}
defaults.update(kwargs)
return super(WeekdayField, self).formfield(**defaults)
def get_internal_type(self):
return "IntegerField"
class WeekdayFormField(forms.MultipleChoiceField):
def __init__(self, *args, **kwargs):
if 'choices' not in kwargs:
kwargs['choices'] = Weekdays.CHOICES
kwargs.pop('max_length', None)
if 'widget' not in kwargs:
kwargs['widget'] = forms.widgets.CheckboxSelectMultiple
super(WeekdayFormField, self).__init__(*args, **kwargs)
def clean(self, value):
super(WeekdayFormField, self).clean(value)
possible_values = [ str(x[0]) for x in Weekdays.CHOICES ]
for v in value:
if not v in possible_values:
raise forms.ValidationError("Day not valid")
return value
使用这个我可以通过Django Admin创建和删除元素,但是当我修改一个值时,我看不到我之前存储的值。我查看了数据库并正确存储了值。
有关如何让我在修改过程中看到Django Admin的当前值的任何想法?
答案 0 :(得分:0)
我有解决方案!方法Weekdays.__unicode__()
和Weekdays.__iter__()
的实施是错误的。
最后,我还在WeekdayField
中更改了下面报告的两种方法。
#Class-type
class Weekdays(object):
...
def __unicode__(self): # Request for the matching
ret = []
for i,ele in enumerate(Weekdays.CHOICES):
if (self.raw & ele[0]) >> i == 1:
ret.append(unicode(ele[0]))
return ','.join(ret)
def __iter__(self):
for i,ele in enumerate(Weekdays.CHOICES):
if (self.raw & ele[0]) >> i == 1:
yield Weekdays(ele[0])
#Field to include in the model
class WeekdayField(models.Field):
...
# DB to PY
def to_python(self, value):
if isinstance(value, int):
return [ wd for wd in Weekdays(value) ]
if isinstance(value, unicode):
return [ wd for wd in Weekdays(int(value)) ]
if isinstance(value, Weekdays):
return value
if isinstance(value, list): #list of Weekdays
wd = []
for val in value:
wd += self.to_python(val)
return wd
#PY to DB
def get_prep_value(self, value):
if isinstance(value, Weekdays):
return value.raw
if isinstance(value, list):
sum_raw = 0
for val in value:
sum_raw += self.get_prep_value(val)
return sum_raw
我希望这会对某人有所帮助!