我有一个简单的模型和更简单的模型表单,但我就是不知道如何为我的表单字段设置初始值或自定义值。
我尝试使用 form.cleaned_data['fieldname'] = value, initial={'field':value}, form.fields['field'].initial = value
,甚至对其进行索引像这样 form.cleaned_data['status'] = Locked.STATUS[0][0]
但我无法让它工作。
郑重声明,我想使用模型中的选择字段。字段名称是“STATUS”,我想在我的 views.py 中设置第一个值(“odlozen”)用作表单字段值。因此,当此函数触发时,form.cleaned_data 需要是 'odlozen' 的 STATUS 值。
PS。不要介意我没有声明我的整个代码,因为这个问题没有必要。谢谢!
让我们从我的代码开始:
模型.py
class Locked(models.Model):
STATUS = (
('odlozen', 'Odložen'), #this is the value
('u_procesu', 'U procesu'),
('ne_javlja_se', 'Ne javlja se'),
('zakazan', 'Zakazan'),
('odustao', 'Odustao'),
('default', 'Izaberite status.'),
)
...
opp_comment = models.CharField(max_length=155, blank=True)
status = models.CharField(max_length=50, choices=STATUS, blank=True) #I set blank=True for no reason, it can be False also.
...
class Meta:
verbose_name = 'Locked'
verbose_name_plural = 'Locked'
get_latest_by = 'locked_name'
def __str__(self):
return smart_str(self.locked_eluid)
这是我的表单.py:
class OppDetaljiForm(forms.ModelForm):
class Meta:
model = Locked
fields = [... ,'status','opp_comment', ...]
labels = {
...
'opp_comment': 'Comment',
'status': 'Status',
...
}
widgets = {
...
'status': forms.HiddenInput(),
'opp_comment': forms.Textarea()
}
我的 View .py:
def odlozi(request, pk):
opp_locked = Locked.objects.get(pk=pk)
form = OppDetaljiForm(instance=opp_locked)
...
if request.method == 'POST':
form = OppDetaljiForm(request.POST or None, instance=opp_locked, initial={'status': 'odlozen'})
if form.is_valid():
form.cleaned_data['status'] = 'odlozen' #?! As I said before, none of my ideas worked.
...
form.save()
...
return redirect('appname:url') # Dont mind me for not declaring my code, since it not necessary
context = {
'form': form,
...
}
return render(request, 'myhtmlpage.html', context)
这是 HTML :
<div class="container" style="position: relative">
<form action="" method="POST">
{% csrf_token %}
<div class="form-row my-4">
<div class="form-group col-md-6 mb-0">
{{ form.status|as_crispy_field }}
</div>
<div class="form-group col-md-12 mb-0">
{{ form.opp_comment|as_crispy_field }}
</div>
...
# Other form fields
...
</div>
<a class="btn btn-light" href="{% url 'appname:url' %}">Back</a>
<button type="submit" class="btn btn-primary" style="float: right">Submit</button>
</form>
</div>
最佳答案
有几种方法:
- 如果您在模型中设置了默认值,afaik 将在相应的
ModelForm
中将其用作初始值
- 或者只是将一个
initial
字典传递给表单的初始化程序:form = OppDetaljiForm(instance=opp_locked, initial={'status': 'odlozen'})
但是请注意,由于您正在传递一个实例 (opp_locked
),因此从实例中获取的值会取代从 initial
中获取的值。
您所说的初始 值是当用户未选择任何开始时在表单中向用户显示的字段值。这不同于覆盖值在用户提交表单(忽略用户输入)之后。您可以在表单的字段清理方法中执行此操作:
# in OppDetaljiForm
def clean_status(self):
status = self.cleaned_data.get('status')
if not status:
status = 'odlozen'
return status
最后,如果用户无法设置 status
,则根本不要将其放入表单(将其从 fields
和您的模板中完全删除)并在保存模型之前将其设置在您的 View 中:
if form.is_valid():
opp_detail = form.save(commit=False) # gives you the instance without saving it
opp_detail.status = 'odlozen' # add values that your form didn't set
opp_detail.save() # now save
或者让表单处理:
class OppDetaljiForm(forms.ModelForm):
status = 'odlozen'
class Meta:
fields = (<list of fields without 'status'!>)
# ...
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.instance.status = self.status # assigns the status to the instance
你说你有六种形式,如果唯一的区别是它们设置的状态,那么只需制作一种形式并将状态传递给 init 方法,这样在你看来你可以做 form = MyForm(request.POST , instance=..., status='odlozen')
例如。
关于python - Django ModelForm 初始或自定义字段值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60059785/