Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get Django form field from model field?

Tags:

I'd like to create a form that includes fields from two separate models, along with some other regular (non-model) fields. The form will create an instance of each model. I don't think I can use inline formsets for this, since I don't want to include all the fields from both models.

I'd like to create the form field without hard-coding the type of the model fields.

I know I can get a form field from a model field using model_field.formfield(). But how can I get the specific model field?

My first solution:

def get_fields(model_class):
    fields = {}
    for f in model_class._meta.fields:
        fields[f.name] = f

class MyForm(forms.Form):
    foo_name = get_fields(Foo)['name'].formfield()
    bar_name = get_fields(Bar)['name'].formfield()
    other_field = ...

Is there an equivalent of get_fields already? Is this a bad idea? I'm uncomfortable relying on the model _meta attribute. Or am I going about this the completely wrong way?

like image 237
harto Avatar asked Apr 06 '10 10:04

harto


People also ask

How do I get form fields in django?

Basically to extract data from a form field of a form, all you have to do is use the form. is_valid() function along with the form. cleaned_data. get() function, passing in the name of the form field into this function as a parameter.

How do you receive data from a django form with a post request?

Using Form in a View In Django, the request object passed as parameter to your view has an attribute called "method" where the type of the request is set, and all data passed via POST can be accessed via the request. POST dictionary. The view will display the result of the login form posted through the loggedin.

Is there a list field for django models?

Mine is simpler to implement, and you can pass a list, dict, or anything that can be converted into json. In Django 1.10 and above, there's a new ArrayField field you can use.

How do you override a field widget in form for model?

Overriding the default fields To specify a custom widget for a field, use the widgets attribute of the inner Meta class. This should be a dictionary mapping field names to widget classes or instances. The widgets dictionary accepts either widget instances (e.g., Textarea(...) ) or classes (e.g., Textarea ).


2 Answers

You also can take a look at django.forms.models.fields_for_model. That should give you a dictionary of fields, and then you can add the fields of the form

like image 153
naw Avatar answered Oct 13 '22 00:10

naw


You should never have to build the fields yourself unless you want some special behavior.

This should be as simple as using two ModelForms and an extra Form inside one <form> tag in your template with one submit button.

in forms.py:

class Model1Form(forms.ModelForm):
    class Meta:
        model = Model1
        fields = ('fields', 'you', 'want')

class Model2Form(forms.ModelForm):
    class Meta:
        model = Model2
        fields = ('fields', 'you', 'want')

class ExtraFieldsForm(forms.Form):
    extra_field = form.TextField() # or whatever field you're looking for

in views.py:

form1 = Model1Form(request.POST or None)
form2 = Model2Form(request.POST or None)
form3 = ExtraFieldsForm(request.POST or None)

if form1.is_valid() and form2.is_valid() and form3.is_valid():
    form1.save()
    form2.save()
    form3.save()

    ...do other stuff like a redirect...

and in the template:

<form method="POST" action="">{% csrf_token %}
    <fieldset>
        {{ form1|as_uni_form }}
        {{ form2|as_uni_form }}
        {{ form3|as_uni_form }}
        <div class="form_block">
            <input type="submit" value="Save both models"/>
        </div>
    </fieldset>
</form>

I'm used to using django-uni-form, but you can render the form fields however you like. Good luck with your site.

like image 41
Casey W. Stark Avatar answered Oct 12 '22 23:10

Casey W. Stark