django

2009-09-11 9 views
8

में किसी प्रपत्र के लिए फॉर्म फ़ील्ड स्वतः उत्पन्न करें मेरे पास कुछ मॉडल हैं और मैं इस डेटा से बहु-चयन फ़ॉर्म बनाना चाहता हूं। तो फॉर्म में प्रत्येक श्रेणी के लिए एक प्रविष्टि होगी और विकल्प उस श्रेणी में कौशल होंगे।django

models.py

class SkillCategory(models.Model): 
    name = models.CharField(max_length=50) 

class Skill(models.Model): 
    name = models.CharField(max_length=50) 
    category = models.ForeignKey(SkillCategory) 

वहाँ स्वत: जनरेट प्रपत्र फ़ील्ड्स के लिए एक रास्ता है? मुझे पता है कि मैं प्रत्येक कौशल श्रेणी के लिए फॉर्म में 'कौशल श्रेणी' प्रविष्टि मैन्युअल रूप से जोड़ सकता हूं, लेकिन इसे मॉडल के रूप में रखने का कारण इतना कौशल है और कौशल श्रेणियों को स्वतंत्र रूप से संपादित किया जा सकता है।

मैं इस तरह कुछ करना चाहता हूँ: (मैं इस कोशिश की, लेकिन यह काम करने के लिए, सटीक त्रुटि याद नहीं है नहीं मिला ...)

forms.py

class SkillSelectionForm(forms.Form): 
    def __init__(*args, **kwargs): 
     super(SkillSelectionForm, self).__init__(*args, **kwargs) 
     for c in SkillCategory.objects.all(): 
      category_skills = [(pk, s.name) for s in c.skill_set.all()] 
      setattr(self, c.name, forms.MultipleChoiceField(choices=category_skills, widget=forms.CheckboxSelectMultiple)) 

समाधान

यह Sk का उपयोग कर एक फार्म क्षेत्र प्रविष्टि बना देता है illCategory.name और कौशल में विकल्प के रूप में विकल्प असाइन करता है। field_name/display_name का उपयोग गैर-एएससीआई श्रेणी के नाम के साथ समस्याओं से बचने के लिए किया जाता है।

forms.py

def get_categorized_skills(): 
    skills = {} 
    for s in Skill.objects.values('pk', 'name', 'category__name').order_by('category__name'): 
     if s['category__name'] not in skills.keys(): 
      skills[s['category__name']] = [] 
     skills[s['category__name']].append((s['pk'], s['name'])) 
    return skills 

class SkillSelectionForm(forms.Form): 
    def __init__(self, *args, **kwargs): 
     super(SkillSelectionForm, self).__init__(*args, **kwargs) 
     skills = get_categorized_skills() 
     for idx, cat in enumerate(skills.keys()): 
      field_name = u'category-{0}'.format(idx) 
      display_name = cat 
      self.fields[field_name] = forms.MultipleChoiceField(choices=skills[cat], widget=forms.CheckboxSelectMultiple, label=display_name) 

उत्तर

1

b-list.org और uswaretech.com से Django में गतिशील रूपों, बनाने पर एक नज़र डालें: एक समाधान है जो अपने मामले पर कैसे गतिशील रूप से निर्माण किया जा सकता है का एक उदाहरण में overkill हो सकता है, कुछ इस तरह है। मॉडलों से फॉर्म सामग्री को गतिशील रूप से बनाने के लिए मैंने इन उदाहरणों का उपयोग करके सफलता प्राप्त की है।

+0

धन्यवाद, यह मुझे सही दिशा में इंगित करता है, मेरे अंतिम समाधान के लिए उपरोक्त मेरा संपादन देखें। – monkut

1

क्या आप चाहते हैं एक formset है। यह आपको पंक्तियों का एक सेट देगा, जिनमें से प्रत्येक एक विशिष्ट कौशल के लिए नक्शे।

Formset documentation और विशेष रूप से formsets for models उत्पन्न करने पर पृष्ठ देखें।

+0

धन्यवाद, यह सही दृष्टिकोण प्रतीत होता है, मुझे बस इस परिप्रेक्ष्य से समस्या को फिर से सोचने की आवश्यकता है। – monkut

2

ठीक है, इसलिए आप इस तरह के फ़ील्ड को फॉर्म पर सेट नहीं कर सकते हैं। फर्म, जब आप DeclarativeFieldsMetaclass देखते हैं, तो फॉर्म के मेटाक्लास को देखें। फर्म (लेकिन फॉर्मों का नहीं। बेसफॉर्म)।

base_fields = [ 
    forms.MultipleChoiceField(choices=[ 
     (pk, s.name) for s in c.skill_set.all() 
    ]) for c in SkillCategory.objects.all() 
] 
SkillSelectionForm = type('SkillSelectionForm', (forms.BaseForm,), {'base_fields': base_fields}) 
+0

फंकी, लेकिन काम करने योग्य लग रहा है। कोड संदर्भ के लिए धन्यवाद! – monkut