SebasSBM
SebasSBM

Reputation: 908

How to choose form depending on model field

I have a django model to define content pages, in which I had a field to choose if I wanted some form to appear or not within the page.

Now I've made a second form. I'd like to use one or another depending on some field filled in ContentPage instance.

To be more specific, I'm stuck with this part:

class ViewContentPage(CreateView):
    model = ContentPage
    # What I'd like to do
    form_class = depending_on_some_ContentPage_field()

    # From here, overriden methods and stuff

The problem is that it seems impossible to get access to kwargs or request at class level definition (in order to load the proper ContentPage record depending on slug extracted from kwargs, and then determine from it's field which form to load)

I've been thinking on different approaches to achieve a similar result, which research led me to find this question: Can I call a view from within another view?. I'm thinking that "making FormViews as a sub-view inside ViewContentPage" would pave the way, or a completely independent view for forms rendered on template level...

Can something like the exposed in pseudo_code above be achieved with some other kind of approach?

EDIT

As @Alasdair reccommended, I override get_form_class() method in my view. It looks like it does what I want, but a little failure which traceback is entirely in Django itself stands in my way.

I use Django v1.8.3, the point where the exception is raised is in django.core.handlers.base.py line 132 (first in the traceback). The exception is:

TypeError: 'instance' is an invalid keyword argument for this function

And the cause of this exception seems to be in django/db/models/base.py line 480 (last in the traceback). Somehow, this class (django.db.models.base.Model) is running even if self = Error in formatting: RelatedObjectDoesNotExist: MyModelForForm2 has no page. Really confusing.

It's not the first time I see an error which traceback doesn't stop anywhere in my source, and even so, correcting the source would eliminate the error. However, I am still stuck on how to correct this without modifying Django itself.

Upvotes: 1

Views: 122

Answers (1)

Alasdair
Alasdair

Reputation: 308839

You can override the get_form_class method. Inside it, you can access self.request and get the slug from self.kwargs.

class ViewContentPage(CreateView):
    model = ContentPage

    def get form_class(self):
        # return correct class based on self.kwargs and self.request

Upvotes: 1

Related Questions