42WaysToAnswerThat
42WaysToAnswerThat

Reputation: 361

django modify FormView fields before form validation

Is there a proper way to modify the form fields before validating the data on a Class Based FormView. More specifically a CreateView. Is necessary to use Class Based views 'cause I'm throwing in a bunch of custom mixins:

class Create(HtmxRequiredMixin, CreatedByMixin, HxFormValidationMixin, BaseMixin, CreateView):
    template_name = 'administration/form.html'
    model = Object
    form_class = Form
    success_url = reverse_lazy('object-list')
    hx_retarget = '#CREATE'
    base = 'object'
    views_list = ('create',)

I used the CreatedByMixin in the DRF viewset for the api rest. it looks like:

class CreatedByMixin:
    def create(self, request, *args, **kwargs):
        data = request.data.copy()
        if request.user.is_authenticated:
            data['created_by'] = request.user.id
        serializer = self.get_serializer(data=data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

I want a similar mixin for my CreateView but I'm not sure what is the proper method to override.

Also, the HxFormValidationMixin already override the form_valid and form_invalid methods.

Upvotes: 0

Views: 74

Answers (2)

Tanveer
Tanveer

Reputation: 1233

Actual implementation of def get_form_kwargs(self): in FormMixin which inherit from ContextMixin. you can access the request using self.request and when you have self.request you can do whatever you want.

def get_form_kwargs(self):
    """Return the keyword arguments for instantiating the form."""
    kwargs = {
        "initial": self.get_initial(),
        "prefix": self.get_prefix(),
    }

    if self.request.method in ("POST", "PUT"):
        kwargs.update(
            {
                "data": self.request.POST,
                "files": self.request.FILES,
            }
        )
    return kwargs 

Upvotes: 1

little_birdie
little_birdie

Reputation: 5867

FormView inherits from FormMixin, which implements the method get_form_kwargs(). By overriding this method, you can mess with the data kwarg before it's passed to the form constructor.

def get_form_kwargs(self):
    kwargs = super().get_form_kwargs()

    if 'data' in kwargs:
       data = kwargs['data'].copy()

       # change whatever you want
       data['foo'] = 'bar'

       # replace the original with the copy
       kwargs['data'] = data

    return kwargs

Upvotes: 1

Related Questions