Mam kilka modeli i chcę wygenerować formularz wielokrotnego wyboru z tych danych. Tak więc formularz zawierałby pozycję dla każdej kategorii, a wybory byłyby umiejętnościami w tej kategorii.Automatyczne generowanie pól formularza dla formularza w 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)
Czy istnieje sposób, aby automatycznie wygenerować pól formularza? Wiem, że mogę ręcznie dodać wpis "SkillCategory" w formularzu dla każdej kategorii SkillCategory, ale powodem, dla którego ma on być model, jest to, że umiejętności i kategorie umiejętności mogą być dowolnie edytowane.
chcę zrobić coś takiego: (próbowałem tego, ale nie zmusić go do pracy, nie pamiętam dokładnej błąd ...)
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))
ROZWIĄZANIE
To tworzy wpis pola formularza przy użyciu Sk illCategory.name i przypisuje wybory, jak te w Skill. nazwa_pola/nazwa_ wyświetlana są używane w celu uniknięcia problemów z nie-ascii nazwami kategorii.
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)
Dzięki, wskazał mi w dobrym kierunku, zobacz moją edycję powyżej dla mojego ostatecznego rozwiązania. – monkut