2015-02-27 3 views
1

Я пытаюсь перенести приложение с существующим db. Я использую db_column для правильной работы с внешними ключами django, используя существующие имена и столбцы базы данных.django forms ForeignKey 'value error должен быть экземпляром'

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 два ряда (идентификаторы 0 и 1) для foo_type 'бар' и 'БАЗ'. Я пытаюсь сделать форму, чтобы добавить запись в таблицу foo, которая будет иметь внешний ключ для foo_type_lookup. Foo может быть баром или базом.

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, когда радио-кнопки меняются. Я нахожу это довольно неуклюжим, но я не уверен в более Джанго способа достичь этого:

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

A ChoiceField не знает, что необходимо принудительно предоставить предоставленное значение конкретному экземпляру модели.

Вместо этого используйте ModelChoiceField.

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

Упса, кажется, что вы хотите, чтобы некоторые очень конкретные отображения логики для ваших значений трудно закодированной в ваш питон, которые не обязательно могут приравнять к вашим строковым представлениям вашей соответствующей модели.

Если это так, отмените форму save, чтобы применить любое принуждение там до того, как реальное сохранение вызывается через super.

Вы можете также вручную применить любой питон логику через commit=False (я замечаю у вас уже есть это заявление, чтобы установить True и, возможно, вы играли с идеей.)

obj = form.save(commit=false) 
obj.foo_lookup_type = MyObject.objects.get(pk=form.cleaned_data['foo_lookup_type']) 
obj.save() 
Смежные вопросы