2015-11-30 5 views
2

Django's ModelChoiceField - это поле формы по умолчанию, используемое для внешних ключей при получении формы из модели с использованием ModelForm. После проверки поле проверит, что выбранное значение существует в соответствующей связанной таблице, и поднимите ValidationError, если это не так.Django ModelChoiceField позволяет создавать объекты

Я создаю форму для Document модели, которая имеет type поле, внешний ключ к Type модели, которая делает только содержать атрибут name. Вот код models.py для ясности

class Type(models.Model): 
    name = models.CharField(max_length=32) 

class Document(models.Model): 
    title = models.CharField(max_length=256) 
    type = models.ForeignKey(Type, related_name='related_documents') 

Вместо стандартного select управления, я использую selectize.js для обеспечения автозаполнения для пользователей. Кроме того, selectize предоставляет параметр «create», который позволяет ввести значение, которое еще не существует в select.

Я хотел бы расширить ModelChoiceField для того, чтобы создать новый объект Type, когда выбранное значение не существует (новое значение будет присвоено name поля, то это должно быть вариантом поля для повторного использования). Если возможно, я хотел бы, чтобы объект не был вставлен в БД до тех пор, пока save() не вызывается в проверенной форме (чтобы предотвратить множественную неудачную проверку, создайте несколько строк в db). Что было бы хорошим способом сделать это в Django? Я попытался заглянуть в документацию и исходный код, попытался переопределить ModelChoiceField и попытался построить это поведение, пробитое на TextField, но я не уверен, что нет более простого способа сделать это.

Я рассмотрел следующие вопросы, но не смог найти ответ.

Я хотел бы, чтобы процесс добавления новых типов как можно проще - то есть: не использовать всплывающее окно, прикрепленный к ' + '. Пользователь должен иметь возможность вводить значение, и значение создается, если оно не существует.

Благодаря

ответ

0

Это кажется, что было бы проще без использования ModelForm. Вы можете создать список всех ваших объектов Type, а затем передать это шаблону в качестве контекстной переменной. Затем вы можете использовать этот список для создания элемента <select>. Затем используйте jquery и selectize, чтобы добавить необходимые атрибуты в форму.

#views.py 
... 
types = Type.objects.all() 
... 



#template.html 
... 
<form action="" method="POST">{% csrf_token %} 
    <input type='text' name='title'> 
    <select name='type' id='id_type'> 
     {% for type in types %} 
      <option value="{{type.id}}">{{type.name}}</option> 
     {% endfor %} 
    </select> 
    <input type='submit'> 
</form> 
<script type='text/javascript'> 
$('#id_type').selectize({ 
    create: true 
    }); 
</script> 
... 

Затем, когда вы получите представление формы, вы можете обработать его в простой функции вида:

if request.method == POST: 
     title_post = request.POST.get('title','') 
     type_post = request.POST.get('type',None) 
     if type_post is not None: 
      try: 
       #If an existing Type was selected, we'll have an ID to lookup 
       type = Type.objects.get(id=type_post) 
      except: 
       #If that lookup failed, we've got a user-inputted name to use 
       type = Type.objects.create(name=type_post) 
      new_doc = Document.objects.create(title=title_post, type=type) 
+0

Это, вероятно, работать, но я надеялся, что я мог бы сохранить все полезные свойства 'ModelForm 'обеспечивает, например, вызов' form.save() '(у фактического' Document' больше полей, чем указано в вопросе). Более того, инкапсуляция всего этого в собственное поле формы была бы приятной :) –

Смежные вопросы