2013-03-01 4 views
11

के रूप में एक फॉर्मेट को Nesting मेरे पास एक django Formset है कि मैं किसी अन्य रूप के बीच में लेआउट करना चाहता हूं। मैं django-crispy-forms उपयोग कर रहा हूँ में लेआउट सेट करने के लिए माता पिता के रूप के __init__:django crispy रूप:

from crispy_forms.helper import FormHelper 
from crispy_forms.layout import Submit, Layout, Field, Div 
def __init__(self, *args, **kwargs): 
    self.helper = FormHelper() 
    self.helper.layout = Layout(
     Div(
      Div(Field('foo'), css_class='span3'), 
      Div(Field('bar'), css_class='span4'), 
      css_class='row' 
      ), 
     Field('baz', css_class='span1'), 
      ... 
      ) 
    self.helper.add_input(Submit('submit', 'Submit', css_class='btn btn-primary offset4')) 

मेरे टेम्पलेट बस प्रपत्र {% crispy %} टैग का उपयोग कर बना देता है।

मैं जानना चाहता हूं कि मुझे फ़ॉर्मेट को कैसे शामिल करना चाहिए। क्या मुझे इसे उपरोक्त init फ़ंक्शन में तुरंत चालू करना चाहिए? मैं वहां इसका उल्लेख कैसे करूं?

वहाँ फार्म और formset कॉम्बो की other examples हैं ऑनलाइन है कि एक के बाद एक क्रमानुसार प्रस्तुत करना है, लेकिन मैं सोच रहा हूँ मैं कैसे वे खस्ता के लेआउट के साथ एक साथ फिट पर अधिक नियंत्रण है कर सकते हैं।

उत्तर

16

मैं खस्ता रूपों को संशोधित करने के बिना इस हल, एक नए क्षेत्र प्रकार है कि एक formset renders बनाने के द्वारा:

from crispy_forms.layout import LayoutObject, TEMPLATE_PACK 

class Formset(LayoutObject): 
    """ 
    Layout object. It renders an entire formset, as though it were a Field. 

    Example:: 

    Formset("attached_files_formset") 
    """ 

    template = "%s/formset.html" % TEMPLATE_PACK 

    def __init__(self, formset_name_in_context, template=None): 
     self.formset_name_in_context = formset_name_in_context 

     # crispy_forms/layout.py:302 requires us to have a fields property 
     self.fields = [] 

     # Overrides class variable with an instance level variable 
     if template: 
      self.template = template 

    def render(self, form, form_style, context, template_pack=TEMPLATE_PACK): 
     formset = context[self.formset_name_in_context] 
     return render_to_string(self.template, Context({'wrapper': self, 
      'formset': formset})) 

यह formset रेंडर करने के लिए एक टेम्पलेट की जरूरत है, जो आप के साथ यह वास्तव में कैसे प्रदान की गई है नियंत्रण देता है:

{% load crispy_forms_tags %} 

<div class="formset"> 
    {% crispy formset %} 
    <input type="button" name="add" value="Add another" /> 
</div> 

तुम बस किसी भी अन्य खस्ता लेआउट तत्व की तरह अपने लेआउट में एक formset एम्बेड करने के लिए उपयोग कर सकते हैं:

self.helper.layout = Layout(
    MultiField(
     "Education", 
     Formset('education'), 
    ), 
+2

एक मामूली संशोधन मैं अनुशंसा करता हूं कि फ़ॉर्मसेट लेआउटऑब्जेक्ट में 'formet_helper' के लिए वैकल्पिक पैरामीटर जोड़ना है। यह वैसे ही काम करता है। इस तरह आप कस्टम सहायक में भी जा सकते हैं। – Alejandro

+1

इन कोडों में कौन सी फाइलें रखी गई हैं? मैं formet.html कहां रखूं? और फॉर्मसेट ('शिक्षा') क्या है; यह कहां से आ रहा है? –

3

यह वर्तमान में क्रिस्पी-रूपों में समर्थित नहीं है। आपका एकमात्र विकल्प |as_crispy_field फ़िल्टर का उपयोग करना होगा (अभी तक दस्तावेज नहीं है, क्षमा करें)।

मैं {% crispy %} टैग के लिए और एक सुविधा शाखा में इस सुविधा के विकास शुरू कर दिया है, यह सब यहाँ समझाया है: https://github.com/maraujop/django-crispy-forms/issues/144

मैं प्रतिक्रिया के लिए देख रहा हूँ, इसलिए यदि आप अभी भी रुचि रखते हैं, पोस्ट करने के लिए स्वतंत्र लग रहा है।

2

qris द्वारा पहले के उत्तर में मामूली संशोधन।

(के रूप में Alejandro ने सुझाव दिया) यह अद्यतन हमारे कस्टम formsetलेआउट वस्तु कैसे formset के क्षेत्रों प्रदान कर रहे हैं नियंत्रित करने के लिए एक FormHelper वस्तु का उपयोग करने के लिए अनुमति देगा।

from crispy_forms.layout import LayoutObject 

from django.template.loader import render_to_string 


class Formset(LayoutObject): 
    """ 
    Renders an entire formset, as though it were a Field. 
    Accepts the names (as a string) of formset and helper as they 
    are defined in the context 

    Examples: 
     Formset('contact_formset') 
     Formset('contact_formset', 'contact_formset_helper') 
    """ 

    template = "forms/formset.html" 

    def __init__(self, formset_context_name, helper_context_name=None, 
       template=None, label=None): 

     self.formset_context_name = formset_context_name 
     self.helper_context_name = helper_context_name 

     # crispy_forms/layout.py:302 requires us to have a fields property 
     self.fields = [] 

     # Overrides class variable with an instance level variable 
     if template: 
      self.template = template 

    def render(self, form, form_style, context, **kwargs): 
     formset = context.get(self.formset_context_name) 
     helper = context.get(self.helper_context_name) 
     # closes form prematurely if this isn't explicitly stated 
     if helper: 
      helper.form_tag = False 

     context.update({'formset': formset, 'helper': helper}) 
     return render_to_string(self.template, context.flatten()) 

टेम्पलेट (formset रेंडर करने के लिए प्रयोग किया जाता है):

{% load crispy_forms_tags %} 

<div class="formset"> 
    {% if helper %} 
    {% crispy formset helper %} 
    {% else %} 
    {{ formset|crispy }} 
    {% endif %} 
</div> 

अब यह सिर्फ किसी भी अन्य खस्ता रूपों लेआउट वस्तु की तरह किसी भी लेआउट में इस्तेमाल किया जा सकता है।

self.helper.layout = Layout(
    Div(
     Field('my_field'), 
     Formset('my_formset'), 
     Button('Add New', 'add-extra-formset-fields'), 
    ), 
) 

# or with a helper 
self.helper.layout = Layout(
    Div(
     Field('my_field'), 
     Formset('my_formset', 'my_formset_helper'), 
     Button('Add New', 'add-extra-formset-fields'), 
    ), 
) 
0

समाधान formset (LayoutObject) ऊपर के आधार पर, आप गठबंधन होगा Django-डायनामिक-formset & खस्ता। अपने आदेश पृष्ठ पर मेरे पास है:

  • आदेश के खंड भाग 1
  • आदेश के साथ इनलाइन formset रूपों गतिशील जोड़ने के
  • आदेश के खंड हिस्सा एन

अब यह सरल और स्पष्ट है, ModelForms कर रहे हैं:

class OrderTestForm(forms.ModelForm): 
def __init__(self, *args, **kwargs): 
    super(OrderTestForm, self).__init__(*args, **kwargs) 
    self.helper = FormHelper(self) 
    self.helper.form_tag = True 
    self.helper.html5_required = True 
    self.helper.form_action = 'test_main' 
    self.helper.layout = Layout(
     'product_norms', #section 1 
     'reference_other', #section 1 
     # rest of the section 1 fields 
     Formset('samples', 'helper'), # inline dynamic forms 
     'checkbox_is_required' # start of section N 
     # other order sections fields 
    ) 
    self.helper.add_input(Submit("submit", "Save order")) 

formset सहायक लेआउट:

012,
class SamplesFormSetHelper(FormHelper): 
def __init__(self, *args, **kwargs): 
    super(SamplesFormSetHelper, self).__init__(*args, **kwargs) 
    self.form_method = 'post' 
    self.html5_required = True 
    self.layout = Layout(
     Fieldset('', 
     'description', 
     'product', # foreign key 
     'DELETE', # delete django-dynamic-formset 
     css_class="formset_row"), # add-rows 
    ) 
    self.form_tag = False 
    self.render_required_fields = False 

जोड़ें /, inlines हटाना आदेश बचत formset संचालन के साथ अपेक्षित तरीके से।

संबंधित मुद्दे