How do you modify form data before saving it while using Django's CreateView?
Asked Answered
F

4

5

I'm using the CreateView of Django and I'm trying to find out how I can modify any text which gets sent before it gets saved. For example, right now I'm only looking to lowercase all the text before saving.

I know I need to use form_valid() but I can't seem to get it right.

forms.py

class ConfigForm(forms.ModelForm):
    class Meta:
        model  = Config
        fields = ["heading", "name", "data", "rating"]

views.py

def form_valid(self, form):
    super().form_valid(form)
    form.fields["heading"].lower()
    form.fields["name"].lower()
    form.fields["data"].lower()
Forspent answered 12/12, 2018 at 11:33 Comment(0)
C
11

That shouldn't be done in form_valid. You should do that in the form itself. Instead of letting CreateView automatically create a form for you, do it explicitly and overwrite the clean method.

class MyForm(forms.ModelForm):
   class Meta:
      model = MyModel
      fields = ('list', 'of', 'fields')

   def clean(self):
       for field, value in self.cleaned_data.items():
           self.cleaned_data['field'] = value.lower()

...

class MyCreateView(views.CreateView):
    form_class = MyForm
Caudell answered 12/12, 2018 at 11:38 Comment(0)
P
3

Override get_form_kwargs method to update the kwargs which instantiates the form.

Solution:

def get_form_kwargs(self):
    # update super call if python < 3
    form_kwargs = super().get_form_kwargs()
    form_kwargs['data']['str_field_name'] = form_kwargs['data']['str_field_name'].lower()

    return form_kwargs

Ref: get_form_kwargs docs

Prytaneum answered 12/12, 2018 at 11:40 Comment(0)
B
1

While it may not be the nicest solution, it can be done like this:

def form_valid(self, form):
    self.object = form.save(commit=False)
    # ...
    self.object.save()

    return http.HttpResponseRedirect(self.get_success_url())
Barny answered 21/2, 2020 at 22:18 Comment(0)
L
0

Just for the record

In the first case

def get_form_kwargs(self):
    # update super call if python < 3
    form_kwargs = super().get_form_kwargs()
    form_kwargs['data']['str_field_name'] = form_kwargs['data'['str_field_name'].lower()
    return form_kwargs

Django complains "This QueryDict instance is immutable". And workaround is

 data = kwargs['data'].copy() # mutable copy
 data['foo'] = 'whatever' #supply the missing default value
 kwargs['data'] = data
Leading answered 6/1, 2022 at 1:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.