2015-10-27 2 views
3

Я хочу, чтобы мои пользователи пишут контент, и я хочу, чтобы они указали, сколько разделов с их заголовками они хотят иметь. Я уже создал небольшую функцию Javascript для вставки новых элементов в существующую форму, которая будет отправлена. Это в настоящее время выглядит следующим образом:Динамическое добавление новых полей к форме в Django

openTextarea.js

var i = 1; 

function opentextarea() { 
    "use strict"; 
    var hr = document.createElement('hr'); 
    var title = document.createElement('input'); 
    title.type = 'text'; 
    title.name = 'title_'+i; 
    title.placeholder = 'Your section title!'; 
    title.className = 'form-control'; 
    var input = document.createElement('textarea'); 
    input.name = 'section_'+i; 
    input.className = 'tiny-mce-init'; 
    var button = document.createElement('button'); 
    var newSection = document.getElementById('newSection'); 
    var form = document.getElementById('guide_form'); 
    form.appendChild(hr); 
    form.appendChild(title); 
    form.appendChild(input); 
    loadTinyMCEEditor(); 
    i++; 
} 

шаблон

{% extends "base.html" %} 

{% load staticfiles %} 
{% block body %} 

<script type="text/javascript" src="{% static "tinymce/js/tinymce/tinymce.min.js" %}"></script> 
<script type="text/javascript" src="{% static "javascripts/openTextarea.js" %}"></script> 
<script type="text/javascript" src="{% static "javascripts/loadTinyMCEEditor.js" %}"></script> 

<div style="width: 60%; margin: 0 auto;"> 

    <hr> 

    <form id="guide_form" class="form-horizontal" method="POST" action="{{ request.get_full_path }}"> {% csrf_token %} 

    <fieldset> 
     {% if form.title.errors %} 
     <div class="class-group error"> 
      <div class="controls">{{ field }} 
      <span class="help-inline"> 
       {% for error in form.title.errors %}{{ error }}{% endfor %} 
      </span> 
      </div> 
     </div> 
     {% else %} 
     <div class="control-group"> 
      <div class="controls">{{ form.title }}</div> 
     </div> 
     {% endif %} 

    <hr> 

     {% if form.public.errors %} 
     <div class="class-group error"> 
      <div class="controls">Check, if you want to make your guide public {{ field }} 
      <span class="help-inline"> 
       {% for error in form.public.errors %}{{ error }}{% endfor %} 
      </span> 
      </div> 
     </div> 
     {% else %} 
     <div class="control-group"> 
      <div class="controls">Check, if you want to make your guide public {{ form.public }}</div> 
     </div> 
     {% endif %} 

    <hr> 

    Neutral cards 

    <hr> 

    {% for card in form.cards %} 
     {{ card }} 
    {% endfor %} 

    <hr> 

    </fieldset> 
    </form> 

<hr> 

<div id="newSection"></div> 
<button class="btn btn-primary" type="button" 
    onclick="opentextarea();"> 
    Add Section! 
</button> 

<hr> 

<div class="form-actions" style="margin-top: 4px;"> 
    <button type="submit" form="guide_form" class="btn btn-success">Submit</button> 
</div> 

</div> 

{% endblock %} 

Когда я проверить элемент, новый раздел отображается в форме.

enter image description here

Видимо новые разделы не в form.cleaned_data, потому что, когда я печатаю это, я просто получить поля я изначально созданных с моей форме:

class CreateGuide(FormView): 
    template_name = 'hsguides/guide_create.html' 
    form_class = GuideForm 
    success_url = '/guides/search-guide/' 

    def get_form_kwargs(self, *args, **kwargs): 
     form_kwargs = super(CreateGuide, self).get_form_kwargs(**kwargs) 
     form_kwargs['hero'] = self.kwargs['hero'] 
     return form_kwargs 

    def form_valid(self, form, *args, **kwargs): 
     # TODO 
     # - check if cards are actually from selected class... 
     # - implement sections 
     form.instance.author = self.request.user 
     form.instance.hero = Hero.objects.get(name=self.kwargs['hero']) 
     dust = 0 
     for card in form.cleaned_data['cards']: 
      dust += Card.objects.get(id=card.id).dust 

     for foo in form.cleaned_data: 
      print(foo) 

     form.instance.dust = dust 
     form.save() 
     return super(CreateGuide, self).form_valid(form) 

Результаты

cards

общественное мнение

название

Который имеет смысл, потому что моя форма выглядит следующим образом

class GuideForm(BootstrapModelForm): 
    class Meta: 
     model = Guide 
     exclude = ('author', 'created', 'modified', 'hero', 'dust', 'rating',) 

    def __init__(self, *args, **kwargs): 
     hero = kwargs.pop('hero', None) 
     super(GuideForm, self).__init__(*args, **kwargs) 
     if hero: 
      self.fields['cards'].queryset = Card.objects.filter(Q(card_class='neutral') | 
                   Q(card_class=hero)) 
     self.fields['title'].widget.attrs['placeholder'] = 'Title of your awesome guide!' 
     self.fields['public'].widget.attrs.update({'class': 'checkbox'}) 

Как можно динамически добавлять новые элементы в форме в Джанго? Любая помощь или предложения высоко оценен!

+1

читать о FormSets – madzohan

ответ

3

Вы можете добавить их после вызова super.

class GuideForm(BootstrapModelForm): 
    class Meta: 
     model = Guide 
     exclude = ('author', 'created', 'modified', 'hero', 'dust', 'rating',) 

    def __init__(self, *args, **kwargs): 
     hero = kwargs.pop('hero', None) 
     super(GuideForm, self).__init__(*args, **kwargs) 

     # add your fields here 
     self.fields['title_1'] = forms.CharField() 

Вы можете проверить это хороший пример https://stackoverflow.com/a/6142749/2698552

+0

Ну, так как ваш ответ будет только один вам повезло получить награду: PI видел этот вопрос, который вы ссылки в вашем посте, прежде чем я спросил мой вопрос, но ничего не мог с этим поделать. Причина, по которой я использовал свою репутацию в этом вопросе, заключалась в том, чтобы люди могли помочь мне с проблемой на более конкретном уровне. Но что бы то ни было .. Вот щедрость :) –

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