Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create dynamic fields in ModelForm (Django)

How do I create fields in ModelForm on the go?

For example, I want to create 3 textboxes (because there are 3 entries in the database table)

 ID  Name   Value 
------------------
 1   Alpha  10   
 2   Beta   91    
 3   Char   800  

How do I display it in this way to the user? Does it involve the _init definition? Is it possible to do a for loop of objects in your model form class to retrieve its values and convert them to a field to be displayed? Appreciate any suggestions.

Alpha 

[textbox]
______
Beta

[textbox]

____

etc..

[Submit]

Here is what I tried to do in the def init of the modelform:

self.fields['myfield'].widget = forms.Textarea()

Can't seem to give me the output, do mind my weak understanding of certain django concepts.

like image 798
ndantonio Avatar asked May 16 '11 02:05

ndantonio


People also ask

How to add dynamic fields in form in Django?

To dynamically add field to a form with Python Django, we can add the form with a for loop. to create the MyForm form that has a for loop in the __init__ method that creates CharField s and add them into the self. fields dictionary dynamically. We set the extra argument to a list we get from request.

How do you make a field non editable in Django?

Every field comes in with built-in validations from Django validators. One can also add more built-in field validations for applying or removing certain constraints on a particular field. editable=False will make the field disappear from all forms including admin and ModelForm i.e., it can not be edited using any form.

How do I add a field in Django?

To answer your question, with the new migration introduced in Django 1.7, in order to add a new field to a model you can simply add that field to your model and initialize migrations with ./manage.py makemigrations and then run ./manage.py migrate and the new field will be added to your DB. Save this answer.


2 Answers

I think that your best bet is, in this case, to stick to Model formsets. For any other case, you can just append new fields to the fields attribute, inside your form's __init__.

def __init__(self, *args, *kwargs):
    super(MyForm, self).__init__(*args, **kwargs)
    self.fields.update({
        'foo': forms.CharField(widget=forms.Textarea()),
        'bar': forms.CharField(widget=forms.Textarea()),
    })

Remember that, in this case, you have to call the parent's __init__ first, so you'll have the .fields available.

like image 129
emyller Avatar answered Nov 30 '22 04:11

emyller


You can also dynamically define form fields using the django.forms.models.ModelFormMetaclass (used by django.forms.models.modelform_factory). This will create a ModelForm class using the fields you specify rather than updating the fields 'on the fly' in the init.

from django import forms
from django.forms.models import ModelForm, ModelFormMetaclass


model = MyModel
fields = {
    'myfield': forms.CharField(widget=forms.Textarea())
}

meta_attrs = {
    'model': model,
}

Meta = type('Meta', (object, ), meta_attrs)

form_class_attrs = {
    'Meta': Meta, 
}

form_class_attrs.update(fields)

MyModelForm = ModelFormMetaclass('MyModelForm', (ModelForm, ), form_class_attrs)
like image 30
Max Peterson Avatar answered Nov 30 '22 06:11

Max Peterson