简体   繁体   中英

How can I create a Django model for a form in which users can choose to add more fields?

Is this the correct way to write out all the fields in models.py and forms.py ? I am sure there must be a cleaner way to do this rather than individually listing out all fields and differentiating them with a number at the end.

I have looked into Django FormSets but I am not sure how I would use that with Django WizardForms.

Thank you

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)

you have ModelForm in django

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's really good, read it.

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

edit : for completed the answer of @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()

You're looking at this the wrong way. Firstly, your model should be updated to reflect your use case. If you don't know the fields ahead of time, you can use a JSONField contained in an ArrayField eg

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

Now that we've got that out of the way, the better way to do what you want is to have Education as a model, and then the Profile model would have a foreign key to Education . ie

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

Then your Profile model would have: education = models.ForeignKey(Education, related_name="profile")

To get a varying number of education forms, you should take advantage of modelformset . Create your EducationForm as a normal modelForm instance, then:

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

Instead of writting the same code 5 times you could just use a ManyToMany field.

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)

  • and then you could define each field seperately
class education_school(models.Model):
    education_school = models.CharField(max_length=500, null=True, blank=True)

and so on with the other fields

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM