将小部件应用于字段时出错

时间:2010-06-25 01:57:50

标签: django django-models django-forms

这是我的模特

class RecipeIngredient(models.Model):
    recipe = models.ForeignKey(Recipe)
    ingredient = models.ForeignKey(Ingredient)
    serving_size = models.ForeignKey(ServingSize)
    quantity = models.IntegerField()
    order = models.IntegerField()
    created = models.DateTimeField(auto_now_add = True)
    updated = models.DateTimeField(auto_now = True)

和我的模特表格

class RecipeIngredientForm(forms.ModelForm):
    recipe_ingredient = forms.CharField()

    class Meta:
        model = RecipeIngredient

        widgets = {
            'serving_size' : forms.Select(attrs={'class' : 'test'}), 
            'recipe_ingredient' : forms.TextInput(),
        }

导航到页面时出现以下错误

Unhandled exception in thread started by <function inner_run at 0x1010faf50>
Traceback (most recent call last):
  File "/Library/Python/2.6/site-packages/django/core/management/commands/runserver.py", line 48, in inner_run
    self.validate(display_num_errors=True)
  File "/Library/Python/2.6/site-packages/django/core/management/base.py", line 245, in validate
    num_errors = get_validation_errors(s, app)
  File "/Library/Python/2.6/site-packages/django/core/management/validation.py", line 28, in get_validation_errors
    for (app_name, error) in get_app_errors().items():
  File "/Library/Python/2.6/site-packages/django/db/models/loading.py", line 146, in get_app_errors
    self._populate()
  File "/Library/Python/2.6/site-packages/django/db/models/loading.py", line 61, in _populate
    self.load_app(app_name, True)
  File "/Library/Python/2.6/site-packages/django/db/models/loading.py", line 78, in load_app
    models = import_module('.models', app_name)
  File "/Library/Python/2.6/site-packages/django/utils/importlib.py", line 35, in import_module
    __import__(name)
  File "/models.py", line 128, in <module>
    RecipeIngredientFormSet = inlineformset_factory(Recipe, RecipeIngredient, extra=1, form=RecipeIngredientForm)
  File "/Library/Python/2.6/site-packages/django/forms/models.py", line 838, in inlineformset_factory
    FormSet = modelformset_factory(model, **kwargs)
  File "/Library/Python/2.6/site-packages/django/forms/models.py", line 669, in modelformset_factory
    formfield_callback=formfield_callback)
  File "/Library/Python/2.6/site-packages/django/forms/models.py", line 407, in modelform_factory
    return ModelFormMetaclass(class_name, (form,), form_class_attrs)
  File "/Library/Python/2.6/site-packages/django/forms/models.py", line 220, in __new__
    opts.exclude, opts.widgets, formfield_callback)
  File "/Library/Python/2.6/site-packages/django/forms/models.py", line 178, in fields_for_model
    formfield = formfield_callback(f, **kwargs)
TypeError: <lambda>() got an unexpected keyword argument 'widget'

但如果我从RecipeIngredientForm中删除此行,则错误消失

'serving_size' : forms.Select(attrs={'class' : 'test'}), 

任何想法我做错了吗?

2 个答案:

答案 0 :(得分:1)

只是不要将Select小部件添加到此字段,它是ModelChoiceField,并且无论如何都会呈现为select框。如果您将Select小部件放在ModelChoiceField上,它将无法正常呈现(将在value中显示 unicode 输出而非ID)。

除非您希望文本输入具有自动完成功能,否则您不需要第一个CharField。

要使用自定义属性显示输入元素,请使用{%field%}标记:

{% field myform.myselect class="XYZ" %}

将其呈现为

<select name="..." class="XYZ">...

我认为你会同意在表单或模型中自定义类和模板是个坏主意。这使得无法调试模板。

答案 1 :(得分:1)

我遇到了类似的问题。

我在modelformset_factory构造函数中指定了一个自定义的“form”kwarg。当表单类具有在其元类中指定的自定义窗口小部件时,这将始终因您描述的错误而失败:

class MyForm(forms.ModelForm):
  class Meta:
    model = MyModel
    widgets = {
        'myField' : forms.fields.TextInput(attrs={'readonly':'readonly'}),
    }

MyFormFactory = modelformset_factory(MyModel,form=MyForm)

更改表单类以在 init 方法中指定自定义小部件似乎解决了这个问题:

class MyForm(forms.ModelForm):
  class Meta:
    model = MyModel
  def __init__(self,*args,**kwargs):
    self.fields['myField'].widget = forms.fields.TextInput(attrs={'readonly':'readonly'})