إنشاء حقول النموذج تلقائيًا لنموذج في جانغو

StackOverflow https://stackoverflow.com/questions/1409192

  •  05-07-2019
  •  | 
  •  

سؤال

لدي بعض النماذج وأريد إنشاء نموذج اختيار متعدد من هذه البيانات.لذلك سيحتوي النموذج على إدخال لكل فئة وستكون الاختيارات هي المهارات الموجودة في تلك الفئة.

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)

هل هناك طريقة لإنشاء حقول النموذج تلقائيًا؟أعلم أنه يمكنني إضافة إدخال "SkillCategory" يدويًا في النموذج لكل فئة 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))

حل

يؤدي هذا إلى إنشاء إدخال حقل نموذج باستخدام SkillCategory.name وتعيين الاختيارات مثل تلك الموجودة في Skill.يتم استخدام field_name/display_name لتجنب المشكلات المتعلقة بغير ascii أسماء الفئات.

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)
هل كانت مفيدة؟

المحلول

ألق نظرة على إنشاء نماذج ديناميكية في Django، من ب-list.org و uswaretech.com.لقد نجحت في استخدام هذه الأمثلة لإنشاء محتوى النموذج ديناميكيًا من النماذج.

نصائح أخرى

حسنًا، لا يمكنك تعيين حقول مثل تلك في Forms.Form، للأسباب التي ستصبح واضحة عندما ترى DeclarativeFieldsMetaclass, ، الفئة التعريفية للforms.Form (ولكن ليس للforms.BaseForm).الحل الذي قد يكون مبالغة في حالتك ولكن مثال على كيفية إنشاء النموذج الديناميكي، هو شيء من هذا القبيل:

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})

ما تريده هو Formset.سيعطيك هذا مجموعة من الصفوف، كل منها يرتبط بمهارة معينة.

انظر وثائق فورمسيت والصفحة خاصة بالتوليد نماذج للنماذج.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top