【发布时间】:2011-06-08 21:09:44
【问题描述】:
我有一个Form。我想包含一个返回模型的隐藏字段。我将在视图中设置它的值;我只需要将它发布到下一页。
我应该在表单类中使用什么字段?
【问题讨论】:
标签: django
我有一个Form。我想包含一个返回模型的隐藏字段。我将在视图中设置它的值;我只需要将它发布到下一页。
我应该在表单类中使用什么字段?
【问题讨论】:
标签: django
返回模型的隐藏字段?那么模型实例 ID?
forms.HiddenInput 小部件应该可以解决问题,无论是在 FK 字段还是在 CharField 中,您都可以将模型实例 ID 放入其中。
class MyForm(forms.Form):
hidden_2 = forms.CharField(widget=forms.HiddenInput())
hidden_css = forms.CharField(widget=forms.MostWidgets(attrs={'style': 'display:none;'}))
我想最快的方法是
class MyForm(forms.Form):
model_instance = forms.ModelChoiceField(queryset=MyModel.objects.all(), widget=forms.HiddenInput())
form = MyForm({'model_instance': '1'})
form.cleaned_data['model_instance']
但我不喜欢提供 MyModel.objects.all() 的想法,如果你要指定一个项目的话。
似乎要避免这种行为,您必须用更小的QuerySet 覆盖表单__init__。
我想我更喜欢老式的方式:
class MyForm(forms.Form):
model_instance = forms.CharField(widget=forms.HiddenInput())
def clean_model_instance(self):
data = self.cleaned_data['model_instance']
if not data:
raise forms.ValidationError()
try:
instance = MyModel.objects.get(id=data)
except MyModel.DoesNotExist:
raise forms.ValidationError()
return instance
【讨论】:
ForeignKey 是一个有效的表单域……它是一个模型域。我宁愿它返回一个模型实例而不是一个整数(当我稍后用form.cleaned_data['field'] 检索它时)
HiddenInput() 更有意义。
Yuji 的回答中的方法在表单上使用了 clean_model_instance 方法,如果您只在代码库中执行此操作一次,这很好。如果您经常这样做,那么您可能会从实现自定义模型字段中受益。
这是我的代码:
from django import forms
class ModelField(forms.Field):
Model = None
def prepare_value(self, value):
"""Inject entities' id value into the form's html data"""
if isinstance(value, self.Model):
return value.id
return value
def to_python(self, value):
"""More or less stolen from ModelChoiceField.to_python"""
if value in self.empty_values:
return None
try:
value = self.Model.objects.get(id=value)
except (ValueError, self.Model.DoesNotExist):
raise forms.ValidationError('%s does not exist'
% self.Model.__class__.__name__.capitalize())
return value
如果您将其用作基类,然后使用您自己的模型对其进行专门化,那么它就会成为有用的基础。例如:
# In app/fields.py
from .models import CustomModel
class CustomModelField(ModelField):
Model = CustomModel
然后你可以将它与你当时需要的任何小部件配对:
# in app/forms.py
class MyForm(forms.Form):
hidden_custom_model_field = CustomModelField(widget=forms.HiddenInput())
other_widget_custom_model_field = CustomModelField(widget=MyCustomWidget())
【讨论】: