【问题标题】:How can I create a Django model for a form in which users can choose to add more fields?如何为用户可以选择添加更多字段的表单创建 Django 模型?
【发布时间】:2020-11-22 16:21:41
【问题描述】:

这是写出 models.pyforms.py 中所有字段的正确方法吗?我确信必须有一种更简洁的方法来做到这一点,而不是单独列出所有字段并在末尾用数字区分它们。

我研究了 Django FormSets,但我不确定如何将它与 Django WizardForms 一起使用。

谢谢

models.py

class Profile(models.Model):
    education_school            = models.CharField(max_length=500, null=True, blank=True)
    education_degree            = models.CharField(max_length=500, null=True, blank=True)
    education_field             = models.CharField(max_length=100, null=True, blank=True)
    education_start             = models.CharField(max_length=100, null=True, blank=True)
    education_end               = models.CharField(max_length=100, null=True, blank=True)
    education_grade             = models.TextField(null=True, blank=True)
    education_description       = models.TextField(null=True, blank=True)

    education_school2           = models.CharField(max_length=500, null=True, blank=True)
    education_degree2           = models.CharField(max_length=500, null=True, blank=True)
    education_field2            = models.CharField(max_length=100, null=True, blank=True)
    education_start2            = models.CharField(max_length=100, null=True, blank=True)
    education_end2              = models.CharField(max_length=100, null=True, blank=True)
    education_grade2            = models.TextField(null=True, blank=True)
    education_description2      = models.TextField(null=True, blank=True)

    education_school3           = models.CharField(max_length=500, null=True, blank=True)
    education_degree3           = models.CharField(max_length=500, null=True, blank=True)
    education_field3            = models.CharField(max_length=100, null=True, blank=True)
    education_start3            = models.CharField(max_length=100, null=True, blank=True)
    education_end3              = models.CharField(max_length=100, null=True, blank=True)
    education_grade3            = models.TextField(null=True, blank=True)
    education_description3      = models.TextField(null=True, blank=True)

    education_school4           = models.CharField(max_length=500, null=True, blank=True)
    education_degree4           = models.CharField(max_length=500, null=True, blank=True)
    education_field4            = models.CharField(max_length=100, null=True, blank=True)
    education_start4            = models.CharField(max_length=100, null=True, blank=True)
    education_end4              = models.CharField(max_length=100, null=True, blank=True)
    education_grade4            = models.TextField(null=True, blank=True)
    education_description4      = models.TextField(null=True, blank=True)

    education_school5           = models.CharField(max_length=500, null=True, blank=True)
    education_degree5           = models.CharField(max_length=500, null=True, blank=True)
    education_field5            = models.CharField(max_length=100, null=True, blank=True)
    education_start5            = models.CharField(max_length=100, null=True, blank=True)
    education_end5              = models.CharField(max_length=100, null=True, blank=True)
    education_grade5            = models.TextField(null=True, blank=True)
    education_description5      = models.TextField(null=True, blank=True)

forms.py

class ProfileFour(forms.Form):
    education_school        = forms.CharField()
    education_degree        = forms.CharField()
    education_field         = forms.CharField()
    education_start         = forms.ChoiceField(choices=years)
    education_end           = forms.ChoiceField(choices=years)    
    education_grade         = forms.CharField(widget=forms.Textarea)
    education_description   = forms.CharField(widget=forms.Textarea)

    education_school2       = forms.CharField()
    education_degree2       = forms.CharField()
    education_field2        = forms.CharField()
    education_start2        = forms.ChoiceField(choices=years)
    education_end2          = forms.ChoiceField(choices=years)    
    education_grade2        = forms.CharField(widget=forms.Textarea)
    education_description2  = forms.CharField(widget=forms.Textarea)

    education_school3       = forms.CharField()
    education_degree3       = forms.CharField()
    education_field3        = forms.CharField()
    education_start3        = forms.ChoiceField(choices=years)
    education_end3          = forms.ChoiceField(choices=years)    
    education_grade3        = forms.CharField(widget=forms.Textarea)
    education_description3  = forms.CharField(widget=forms.Textarea)

    education_school4       = forms.CharField()
    education_degree4       = forms.CharField()
    education_field4        = forms.CharField()
    education_start4        = forms.ChoiceField(choices=years)
    education_end4          = forms.ChoiceField(choices=years)    
    education_grade4        = forms.CharField(widget=forms.Textarea)
    education_description4  = forms.CharField(widget=forms.Textarea)

    education_school5       = forms.CharField()
    education_degree5       = forms.CharField()
    education_field5        = forms.CharField()
    education_start5        = forms.ChoiceField(choices=years)
    education_end5          = forms.ChoiceField(choices=years)    
    education_grade5        = forms.CharField(widget=forms.Textarea)
    education_description5  = forms.CharField(widget=forms.Textarea)

【问题讨论】:

    标签: python django django-models django-forms django-formwizard


    【解决方案1】:

    你在 django 中有 ModelForm

    class ProfileFour(form.ModelForm)
        class Meta:
           model = Profile
           fields = '__all__'  # you wand all field
           # or 
           fields = ['education_school', 'education_degree' ..] # name the field you want
    

    doc django 非常好,请阅读。

    https://docs.djangoproject.com/fr/3.0/topics/forms/modelforms/

    编辑:用于完成@Countour-Integral 的答案

    class Profil(models.Model)
       username = models.charField()
       ...
    
    class Education(models.Model)
        profil = models.ForeignKey(Profil)
        school = models.CharField()
        degree = models.IntegerField()
        field = models.CharField()
        start = models.DateField()
        end = models.DateField()
        grade = models.CharField()
        description = models.textField()
    

    【讨论】:

    • 这可以存储教育字段 5 次吗?
    • 5 次及以上,请在管理面板中查看。
    • 试过了,但这会将教育数据分成不同的模型,问题与以前相同。我将不得不复制每个字段 5 次,即 school1、school2、school3 等......我正在寻找一种方法,就像你上面写的那样,为每个字段只写一次。
    • 我认为你的做法是错误的。检查文档docs.djangoproject.com/fr/3.0/ref/models/fields/…
    【解决方案2】:

    您可以只使用 ManyToMany 字段,而不是编写相同的代码 5 次。

    class Profile(models.Model):
        education_school            = models.ManyToManyField( blank=True)
        education_degree            = models.ManyToManyField( blank=True)
        education_field             = models.ManyToManyField( blank=True)
        education_start             = models.ManyToManyField( blank=True)
        education_end               = models.ManyToManyField( blank=True)
        education_grade             = models.ManyToManyField( blank=True)
        education_description       = models.ManyToManyField( blank=True)
    
    
    • 然后您可以分别定义每个字段
    class education_school(models.Model):
        education_school = models.CharField(max_length=500, null=True, blank=True)
    

    其他字段以此类推

    【讨论】:

    • 出现此错误:无法更新模型字段 (仅允许非关系和外键)。
    【解决方案3】:

    你看错了。首先,您的模型应该更新以反映您的用例。如果您不提前知道这些字段,您可以使用 JSONField 包含在 ArrayField 中,例如

    education = ArrayField(models.JSONField(default=dict), size=10, default=list)

    既然我们已经解决了这个问题,更好的方法是使用Education 作为模型,然后Profile 模型将具有Education 的外键。即

    class Education(models.Model):
      school = models.CharField(max_length=50)
      degree = models.CharField(max_length=50)
      ...rest of fields
    

    那么您的Profile 模型将具有: education = models.ForeignKey(Education, related_name="profile")

    要获得不同数量的教育表格,您应该利用modelformset。将您的 EducationForm 创建为普通的 modelForm 实例,然后:

    EducationFormSet = modelformset_factory(Education, form=EducationForm, max_num=10, extra=1)
    

    【讨论】:

      猜你喜欢
      • 2021-10-07
      • 1970-01-01
      • 1970-01-01
      • 2019-02-20
      • 1970-01-01
      • 1970-01-01
      • 2015-10-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多