gpt4 book ai didi

python - Django 自定义 MultiWidget 保留旧值

转载 作者:太空狗 更新时间:2023-10-30 01:24:40 25 4
gpt4 key购买 nike

我创建了一个简单的自定义 MultiValueFieldMultiWidget 用于输入出生日期但允许单独输入日、月和年。理由是该应用程序用于输入历史数据,因此这些字段中的一个或多个可能是未知的。在面向用户的网站上还有一个显示“未知”的复选框。

我发现一切正常,除了当我在管理站点中保存一个对象的实例并去创建一个新实例时,空白的管理表单显示上一个条目的日期值:

Custom MultiWidget

对于新条目,所有这些字段都应为空白。

看起来该字段没有正确重新初始化,但我不确定应该在哪里重新初始化。我通过在表单中​​检查是否重新初始化字段来添加一个解决方法,但我觉得这应该在自定义字段/小部件中完成。

示例代码:

    class CustomDateWidget(forms.MultiWidget):
"""Custom MultiWidget to allow saving different date values."""
template_name = 'myapp/widgets/custom_date_widget.html'

def __init__(self, attrs=None):
_widgets = (forms.NumberInput(attrs=({'placeholder': 'DD'})),
forms.NumberInput(attrs=({'placeholder': 'MM'})),
forms.NumberInput(attrs=({'placeholder': 'YYYY'})),
forms.CheckboxInput())
super().__init__(_widgets, attrs)

def decompress(self, value):
if value:
return value
else:
return '', '', '', False

def value_from_datadict(self, data, files, name):
value_list = [
widget.value_from_datadict(data, files, name + '_%s' % i)
for i, widget in enumerate(self.widgets)
]
return value_list


class CustomDateField(forms.MultiValueField):
"""Custom MultiValueField to allow saving different date values."""
def __init__(self, **kwargs):
fields = (forms.IntegerField(min_value=1, max_value=31), forms.IntegerField(min_value=1, max_value=12),
forms.IntegerField(min_value=1800, max_value=9999), forms.BooleanField())
super().__init__(fields=fields, widget=CustomDateWidget, require_all_fields=True,
**kwargs)

def compress(self, data_list):
return data_list


class PersonAdminForm(forms.ModelForm):
"""Custom Person admin form."""
date_of_birth = CustomDateField(required=False)

class Meta:
model = Person
fields = '__all__'

def __init__(self, *args, **kwargs):
super(PersonAdminForm, self).__init__(*args, **kwargs)
# Dirty workaround?
if not self.instance.pk:
self.fields['date_of_birth'] = CustomDateField(required=False)

...

小部件模板:

    <style>
.custom-date-widget-container {
padding-right: 15px;
}
.custom-date-widget td {
width: 25%;
}
.custom-date-widget td > input {
width: 100%;
box-sizing: border-box;
}
</style>
{% spaceless %}
<div class="custom-date-widget-container">
<table class="custom-date-widget">
<thead>
<tr>
<th>Day</th>
<th>Month</th>
<th>Year</th>
<th>Unknown</th>
</tr>
</thead>
<tbody>
<tr>
{% for widget in widget.subwidgets %}
<td>{% include widget.template_name %}</td>
{% endfor %}
</tr>
</tbody>
</table>
</div>
{% endspaceless %}

最佳答案

经过进一步挖掘,我发现问题不在于小部件,而在于 PersonAdmin 类。

除其他事项外,如果对象已经存在,我会在此处设置初始值:

def get_form(self, request, obj=None, change=False, **kwargs):
form = super(PersonAdmin, self).get_form(request, obj, **kwargs)
if obj and type(obj) == Person:
person = obj
form.base_fields['date_of_birth'].initial = [person.dob_day, person.dob_month, person.dob_year, person.dob_unknown]

我没有意识到的是,如果创建一个新对象,字段不会自动设置为空,而是保留之前设置的值。

添加以下内容解决了问题:

    else:
form.base_fields['date_of_birth'].initial = ['', '', '', False]

最后它比我想象的要简单,只是我把自己扔进了一个兔子洞,以为是小部件。

关于python - Django 自定义 MultiWidget 保留旧值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56018355/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com