【问题标题】:Django Forms: Hidden model field?Django Forms:隐藏模型字段?
【发布时间】:2011-06-08 21:09:44
【问题描述】:

我有一个Form。我想包含一个返回模型的隐藏字段。我将在视图中设置它的值;我只需要将它发布到下一页。

我应该在表单类中使用什么字段?

【问题讨论】:

    标签: django


    【解决方案1】:

    返回模型的隐藏字段?那么模型实例 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'] 检索它时)
    • forms.MostWidgets?意思是大多数可用的小部件?
    • @fanny 是的,你应该可以通过设置 style 属性简单地隐藏小部件,但HiddenInput() 更有意义。
    【解决方案2】:

    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())
    

    【讨论】:

      猜你喜欢
      • 2011-09-13
      • 2011-01-06
      • 2010-12-11
      • 2016-05-31
      • 2011-02-16
      • 2011-10-08
      • 1970-01-01
      • 2016-02-14
      • 2016-10-10
      相关资源
      最近更新 更多