Passing a url argument as a form initial value?

Hi! I need to pass a url argument as a form initial value:
How can i do that? Y need to get the argument in view but i can’t.

Error:

Thanks!

urls:

path('add_imageWithInstallationId/<int:id>/',
        views.ImageWithInstallationIdAddView.as_view(),
        name='add_imageWithInstallationId'
    ),

views:

def getId(request, *args, **kwargs):
    installationId = request.GET.get(id)
    return installationId

class ImageWithInstallationIdAddView(LoginRequiredMixin, CreateView):
    template_name = "installation/add_image.html"
    model = ImageInstallation
    form_class = AddImageForm(initial={'image_imageInstallation':getId})
    success_url = '/installation/'

forms:


class AddImageForm(forms.ModelForm):
    class Meta:
        model = ImageInstallation
        fields = ('__all__')
    def __init__(self, *args, **kwargs):
        super(AddImageForm, self).__init__(*args, **kwargs)
        self.fields['installation'].widget.attrs.update({'class': 'form-control'})
        self.fields['installation'].label="Instalación"
        self.fields['image_imageInstallation'].widget.attrs.update({'class': 'form-control'})
        self.fields['image_imageInstallation'].label="Archivo de imagen"

The issue you’re facing is here:

The form_class attribute is looking for a class, not an instance of a class.

What you’re looking to do is change an individual instance of that class, not the class itself.

Instead of overriding the form_class attribute, you want to override the get_form() method to create the instance of the form desired.

Thanks KenWhitesell. I am not sure if you say that:

View:

class ImageWithInstallationIdAddView(LoginRequiredMixin, CreateView):
    template_name = "installation/add_image.html"
    model = ImageInstallation
    form_class = AddImageForm
    success_url = '/installation/'
    login_url = reverse_lazy('users_app:user-login')

    def get_form_kwargs(self, *args, **kwargs):
        kwargs = super(ImageWithInstallationIdAddView, self).get_form_kwargs(*args, **kwargs)
        print(kwargs)
        kwargs['id'] = self.kwargs['id']
        return kwargs

When i print kwargs i can see that:


{'initial': {}, 'prefix': None, 'instance': None}

Not get_form_kwargs, get_form.

The get_form function returns the form for the CreateView class.

The default implementation returns an instance of the form_class. Instead of that, you want to return the instance of form_class, but with whatever fields you want initialized set to the desired values.

Two resources I recommend for understanding the Generic Class-Based Views is the Classy Class-Based View web site and the CBV Diagrams site. In particular, the classy class-based view site makes it easy to follow the chain of function calls.

Mmm Ok, but i need to use the url argument as initial value. Thatś posible with get_form() ? I am trying that… ; )

Urls:

path('add_imageWithInstallationId/<int:id>/',
        views.ImageWithInstallationIdAddView.as_view(),
        name='add_imageWithInstallationId'
    ),

Views:

class ImageWithInstallationIdAddView(LoginRequiredMixin, CreateView):
    template_name = "installation/add_image.html"
    model = ImageInstallation
    form = get_form
    form['image_imageInstallation'] = self.get_form_kwargs('id')
    form_class = form
    login_url = reverse_lazy('users_app:user-login')
    
    def get_form(self, form_class=None):
        if form_class is None:
            form_class = self.get_form_class()
        return form_class(**self.get_form_kwargs())

Ok, let’s look at this from another direction.

First:

You were more correct with your earlier version

This is all you need at the class level.

Now, much earlier, you had:

This is essentially what you want to return from get_form

So, you want to replace that generic **self.get_form_kwargs with whatever parameters you need to pass to the constructor.