django表单ForeignKey'值错误必须是实例'

时间:2015-02-27 18:32:14

标签: javascript django forms radio-button foreign-keys

我正在尝试使用现有数据库移植应用程序。我正在使用db_column在使用现有数据库名称和列时正确地使用django模型外键。

models.py

class foo(models.Model):
  foo_id = models.AutoField(primary_key=True, blank=False, null=False)
  foo_name = models.CharField(max_length=500, blank=True, null=True)
  foo_type_lookup = models.ForeignKey('foo_type_lookup', to_field="foo_type_id", db_column="foo_type", blank=True, null=True)

class foo_type_lookup(models.Model):
  foo_type_id = models.AutoField(primary_key=True, blank=False, null=False)
  foo_type = models.CharField(max_length=500, blank=False, null=False)

表foo_type_lookup有两行(ids 0和1),用于foo_type'bar'和'baz'。我正在尝试创建一个表单来在foo表中添加一条记录,该表将有一个foo_type_lookup的外键。 Foo可以是bar或baz。

views.py

   def add_foo(request):
        action = '#'
        errors = None
        if request.method == 'POST':
            form = FooForm(request.POST)

            if form.is_valid():

                form.save(commit=True)

                return home(request)
            else:
                # The supplied form contained errors - just print them to the terminal.
                errors = form.errors
        else:
            # If the request was not a POST, display the form to enter details.
            form = FooForm()

        # Bad form (or form details), no form supplied...
        # Render the form with error messages (if any).
        return render(request, 'foo/add_foo.html', {'form' : form, 'errors' : errors, 'action' : action})

forms.py

CONTACT_FOO_CHOICES = [[0,'Bar'],[1,'Baz']]

class FooForm(forms.ModelForm):
    foo_type_lookup = forms.ChoiceField(widget=RadioSelect(), choices=CONTACT_FOO_CHOICES)
    foo_name = forms.CharField(label='First Name', max_length=500, required=False)

    class Meta:
        model = foo 

        fields = ('foo_name','foo_type_lookup')

我必须遍历模板中的表单对象,以便在更改单选按钮时添加jQuery函数。我觉得这很笨重,但我不确定更多的django方法来实现这个目标:

add_foo.html

<h2>add_foo.html</h2>
<form action="{{action}}" method="post" role="form">
    {% csrf_token %}
    {% for field in form %}
        {% if field.auto_id = 'id_foo_type_lookup' %}
           {% for choice in form.foo_type_lookup.field.choices %}
            <li>
              <label for="id_{{ field.html_name }}_{{ forloop.counter0 }}">
                  <input type="radio"
                    id="id_{{ field.html_name }}_{{ forloop.counter0 }}"
                    value="{{ choice.0 }}"
                    {% if choice.0 == '0' %}
                      checked="true"
                    {% endif %}
                    name="{{ field.html_name }}"
                    onchange="someFunction('id_{{ field.html_name }}_{{ forloop.counter0 }}')"/>
                   {{ choice.1 }}
              </label>
            </li>
            {% endfor %}
        {% else %}
        <div class="formfield_err">{{ field.help_text }}</div>
          <div id="{{ field.auto_id }}_container" >
              <div class="formfield_divlbl">{{ field.label_tag }}
              </div>
              <div class="formfield_divfld">{{ field }}
                  {% if field.field.required %}
                  <span class="required">*</span>
                  {% endif %}
              </div>
              <div id="{{ field.auto_id }}_errors">{{ field.errors }}
              </div>
          </div><div class="clear" style="margin-bottom:12px;"></div>
        {% endif %}
    {% endfor %}

    <input type="submit" value="Submit" />
</form>

我收到错误:

无法指定“'0'”:“foo.foo_type_lookup”必须是“foo_type_lookup”实例。

如何布局类型查找的单选按钮以添加onchange javascript并为我的ModelForm提供一个'foo_type_lookup'对象,以便数据保存到数据库中?

1 个答案:

答案 0 :(得分:1)

ChoiceField不知道需要将提供的值强制转换为特定的模型实例。

改为使用ModelChoiceField

https://docs.djangoproject.com/en/1.7/ref/forms/fields/#modelchoicefield

糟糕,似乎你想要一些非常具体的显示逻辑,将你的值硬编码到你的python中,这可能不一定等同于你相关模型的字符串表示。

如果是这样,请覆盖您的表单save,以便在通过super调用真实保存之前应用任何强制措施。

你也可以通过commit=False手动应用任何python逻辑(我注意到你已经将该语句设置为True,也许你正在玩这个想法。)

obj = form.save(commit=false)
obj.foo_lookup_type = MyObject.objects.get(pk=form.cleaned_data['foo_lookup_type'])
obj.save()