36
votes

Say I have a form that looks like this:

forms.py

class CreateASomethingForm(ModelForm):
    class Meta:
        model = Something
        fields = ['field2', 'field3', 'field4']

I want the form to have these three fields. However my Somethingclass also has field1. My question is - how do I add data to field1, if I am not using the ModelForm to collect the data. I tried doing something like this, but it isn't working and I am unsure on the proper way to solve this:

views.py

def create_something_view(request):
    if (request.method == 'POST'):
        # Create an object of the form based on POST data
        obj = CreateASomething(request.POST)
        # ** Add data into the blank field1 ** (Throwing an error)
        obj['field1'] = request.user
        # ... validate, save, then redirect 

The error I receive is:

TypeError: 'CreateAClassForm' object does not support item assignment

In Django, what is the proper way to assign data to a ModelForm object before saving?

4

4 Answers

76
votes
form = CreateASomething(request.POST)
if form.is_valid():
    obj = form.save(commit=False)
    obj.field1 = request.user
    obj.save()
7
votes

Sometimes, the field might be required which means you can't make it past form.is_valid(). In that case, you can pass a dict object containing all fields to the form.

   if request.method == 'POST':
       data = {
        'fields1': request.user,
        'fields2': additional_data,
       }
       form = CreateASomethingForm(data)

    if form.is_valid():
        form.commit(save)
2
votes

There are two ways given by Django official LINK : https://docs.djangoproject.com/en/3.0/topics/forms/modelforms/

Method 1]

author = Author(title='Mr')
form = PartialAuthorForm(request.POST, instance=author)
form.save()

Method 2]

form = PartialAuthorForm(request.POST)
author = form.save(commit=False)
author.title = 'Mr'
author.save()
1
votes

Here is a more suitable way to add data especially used during testing:

First convert an existing entry into a dictionary with the model_to_dict function

from django.forms.models import model_to_dict

...

valid_data = model_to_dict(entry)

Then add the new data into this dictionary

valid_data['finish_time'] = '18:44'

This works better than setting the value in the form

update_form.finish_time = '18:44'

Create the form with the valid data and the instance

update_form = UserEntryForm(valid_data, instance=entry)

Do any assertions you require:

self.assertTrue(update_form.is_valid())
entry = update_form.save()
self.assertEqual(
    entry.status,
    1
)