Django:遍历自定义选择字段的选项
我正在使用一个自定义的MM/YY字段和小部件,参考了这个例子。我想遍历小部件类中定义的每个月和每年的选项,以便给与数据库中存储的MM/YY值对应的选项加上“selected='selected'”。我觉得这样做有点麻烦,所以如果你有更好的想法,请在这里分享。
class MonthYearWidget(forms.MultiWidget):
def __init__(self, attrs=None):
months = (
('01', 'Jan (01)'),
('02', 'Feb (02)'),
('03', 'Mar (03)'),
('04', 'Apr (04)'),
('05', 'May (05)'),
('06', 'Jun (06)'),
('07', 'Jul (07)'),
('08', 'Aug (08)'),
('09', 'Sep (09)'),
('10', 'Oct (10)'),
('11', 'Nov (11)'),
('12', 'Dec (12)'),
)
year = int(datetime.date.today().year)
year_digits = range(year, year+10)
years = [(year, year) for year in year_digits]
widgets = (forms.Select(attrs=attrs, choices=months), forms.Select(attrs=attrs, choices=years))
super(MonthYearWidget, self).__init__(widgets, attrs)
def decompress(self, value):
if value:
return [value.month, value.year]
return [None, None]
def render(self, name, value, attrs=None):
try:
value = datetime.date(month=int(value[0]), year=int(value[1]), day=1)
except:
value = ''
return super(MonthYearWidget, self).render(name, value, attrs)
class MonthYearField(forms.MultiValueField):
def __init__(self, *args, **kwargs):
forms.MultiValueField.__init__(self, *args, **kwargs)
self.fields = (forms.CharField(), forms.CharField(),)
def compress(self, data_list):
if data_list:
return datetime.date(year=int(data_list[1]), month=int(data_list[0]), day=1)
return datetime.date.today()
然后我在模板中遇到了问题。我搞不清楚月份和年份的可迭代列表的名字是什么(如果有的话)。找到这个可迭代列表就是问题所在;我已经计划使用一个ifequal语句来确定“selected='selected'”应该应用于哪个选项。目前我只尝试过遍历月份。
<form action="#" method="POST">
{% csrf_token %}
<p>{{ form.from_email.label_tag }}: {{ form.from_email }}</p>
<p>{{ form.working_month.label_tag }}:
<select name="working_month_0" id="id_working_month_0">
{% for i in form.working_month.data_list %}
<option value="{{ i }}">{{ option.from_email }}</option>
{% endfor %}
</select>
<p><input type="submit" value="Change Settings Now" /></p>
</form>
感谢大家提供的任何指导。
编辑:这是通用视图:
def option_edit(request,option_id):
try:
option = Option.objects.get(pk=option_id)
except Option.DoesNotExist:
raise Http404
return create_update.update_object(
request,
form_class = OptionForm,
template_name = 'options.html',
template_object_name = 'option',
object_id = option_id,
post_save_redirect = '/some/address/' + option_id + '/edit/'
)
... 还有表单类:
class OptionForm(ModelForm):
class Meta:
model = Option
working_month = MonthYearField(widget=MonthYearWidget)
我觉得模型也很重要:
class Option(models.Model):
from_email = models.EmailField()
working_month = models.DateField()
我需要在自定义表单字段之外再创建一个自定义模型字段吗,还是可以直接使用这个设置?
2 个回答
2
Django表单的神奇之处在于,你不需要做太多事情。只要通过名字调用表单中的选择字段,它就会自动渲染出来,并根据传入表单的初始数据或实例数据,选择正确的选项。
{{form.working_month}}
如果你还是遇到问题,可以把表单类也发上来吗?
祝你好运!
编辑
在你发的链接的第一个评论中,这个问题已经被提到。评论者提供了这段代码
def __init__(self, *args, **kwargs):
forms.MultiValueField.__init__(self, *args, **kwargs)
self.fields = (forms.CharField(), forms.CharField(),)