大家好我有以下定义如下的表格。如果它是传递fte_assignment
对象的表单,如果它不是None
,那么我想要禁用似乎正在工作的用户字段。问题是,当我提交表单时,我收到以下字段错误Select a valid choice. That choice is not one of the available choices.
我想知道我可以更改哪些字段仍然被禁用put会通过验证吗?下面我将包含所需的表单定义信息和视图中的调用。
forms.py
class TeacherForm(forms.Form):
def __init__(self, *args, **kwargs):
self.location = kwargs.pop('location', None)
self.end_year = kwargs.pop('end_year', None)
# fte_assignment gets passed in if it is an edit this helps
# with when to fire off our clean method logic
self.fte_assignment = kwargs.pop('fte_assignment', None)
super(TeacherForm, self).__init__(*args, **kwargs)
# THIS IS WHERE I DISABLE THE FORM
if self.fte_assignment:
self.fields['user'].disabled = True
user = forms.ModelChoiceField(
label='Employee',
queryset=User.objects.all()
)
room = forms.CharField(max_length=6)
extension = forms.IntegerField()
job = forms.ModelChoiceField(
queryset=Job.objects.all()
)
views.py
fte_assignment = FTEFutureAssignment.objects.get(pk=fte_id)
form_kwargs = {
'user': fte_assignment.user,
'room': fte_assignment.room,
'extension': fte_assignment.extension,
'job': fte_assignment.job
}
form = TeacherForm(
request.POST or None,
initial=form_kwargs,
location=location,
end_year=end_year,
fte_assignment=fte_assignment
)
teacher_form.html
<form
method="post"
novalidate
action="
{% if not fte_assignment %}
{% url 'position_control:teacher_form_add' location_id tab %}
{% else %}
{% url 'position_control:teacher_form_edit' location_id fte_assignment.id %}
{% endif %}
">
{% csrf_token %}
<div class="form-row">
<div class="form-group col-4">
{{ form.errors.user }}
<label for="">{{ form.user.label }}</label>
{{ form.user }}
</div>
<div class="form-group col-2">
{{ form.errors.room }}
<label for="">{{ form.room.label }}</label>
{{ form.room }}
</div>
<div class="form-group col-2">
{{ form.errors.extension }}
<label for="">{{ form.extension.label }}</label>
{{ form.extension }}
</div>
<div class="form-group col-4">
{{ form.errors.job }}
<label for="">{{ form.job.label }}</label>
{{ form.job }}
</div>
</div>
<div class="form-row">
<div class="form-group col">
<button type="submit" class="btn ok">Submit</button>
</div>
</div>
<a href="{% url 'position_control:teacher_list' location_id %}"><i class="far fa-arrow-circle-left"></i> Return to Teacher List</a>
</form>
答案 0 :(得分:1)
对于需要但不应由用户编辑的字段,您通常希望隐藏字段但不禁用该字段
if self.fte_assignment:
self.fields['user'].widget = forms.HiddenInput
然后在你的模板中:
{% if form.fte_assignment %}
{{ form.user }}
{% else %}
<div class="form-group col-4">
{{ form.errors.user }}
<label for="">{{ form.user.label }}</label>
{{ form.user }}
</div>
{% endif %}
答案 1 :(得分:0)
您必须在用户MultiChoiceField中添加required = False。
user = forms.ModelChoiceField(
label='Employee',
required=False,
queryset=User.objects.all()
这意味着对于self.fte_assignment没有选择required 不是无案例。 您已禁用用户字段,但未在表单级别将其设置为空。
答案 2 :(得分:0)
只是想把我的工作留给解决方案我想出了原来的问题,以防它将来会帮助任何人。在模板中,如果是编辑,我只是使表单呈现用户字段的值而不是实际字段本身。
{% if not form.initial %}
{{ form.errors.user }}
<label for="">{{ form.user.label }}</label>
{{ form.user }}
{% else %}
<label for="">{{ form.user.label }}</label>
<p>{{ form.initial.user.last_name }}, {{ form.initial.user.first_name }}</p>
{% endif %}
然后在forms.py
中,我对用户字段进行了更改,将其定义为:
user = forms.ModelChoiceField(
label='Employee',
required=False,
queryset=User.objects.all()
)
然后我手动清理用户字段。我之所以这样做的原因是因为如果它是一个编辑并且fte_assignment具有某个属性(业务需求我不会进入),那么值永远不会改变所以我只是从这里的对象返回它。
def clean_user(self):
user = self.cleaned_data.get('user', None)
# If it is an edit check to see if fte_assingment has assignment so
# we know we are editing a current year object. If it is current
# year object just return the user from this method so that it
# gets set in the request.POST and is valid. This is done because
# in current year users cannot be edited.
if self.fte_assignment:
if hasattr(self.fte_assignment, 'assignment'):
return self.fte_assignment.assignment.user
# Manually handle user validation
if not user:
raise forms.ValidationError('This field is required.')
return user
我不确定解决方案有多干净,但这对我有用,显然任何批评都是受欢迎的。