adrianmcli
adrianmcli

Reputation: 1996

__init__() got an unexpected keyword argument 'user_id'; Classed Based Views

I got the error as stated in the title above. I am trying to feed the form the user_id since my model requires that in order to add a 'table'. However, my use of get_form_kwargs seems to be problematic.

This is the model:

from django.db import models
from django.contrib.auth.models import User

class Vtable(models.Model):
    user = models.ForeignKey(User)
    table_name = models.CharField(max_length=200)
    added_date = models.DateTimeField('date added')

class Vdata(models.Model):
    table_id = models.ForeignKey(Vtable)
    table_pk = models.IntegerField()
    column_1 = models.CharField(max_length=200)
    column_2 = models.CharField(max_length=200)
    added_date = models.DateTimeField('date added')

This is the view:

from django.shortcuts import render
from django.http import HttpResponse
from django.views import generic
from vtables.models import Vtable

class CreateTableView(generic.CreateView):

    model = Vtable
    fields = ['table_name']

    def get_form_kwargs(self):
        # pass "user" keyword argument with the current user to your form
        kwargs = super(CreateTableView, self).get_form_kwargs()
        kwargs['user_id'] = self.request.user
        return kwargs

Upvotes: 1

Views: 1783

Answers (2)

knbk
knbk

Reputation: 53699

The form class generated by a CreateView (or any model form for that matter) does not have an _id field for any foreign key. Instead, it has a field user which is a ModelChoiceField.

Furthermore, that logic should not be contained in your form. A form is merely a means of capturing and validating user input. Which user creates an object is not user input, and such logic should be in your view, e.g.:

class CreateTableView(generic.CreateView):

    model = Vtable
    fields = ['table_name']

    def form_valid(self, form):
        form.instance.user = self.request.user
        return super(CreateTableView, self).form_valid(form)

Upvotes: 1

Burhan Khalid
Burhan Khalid

Reputation: 174662

In order to pass a custom value to the form, you'll have to create your own form class and pass that into the view. The default form class that the view creates doesn't know what to do with your user_id argument, and that's where the error comes from.

Here is an example on how to pass a custom form class, first the form class:

class MyForm(forms.ModelForm):
    class Meta:
        model = Vtable

    def __init__(self, *args, **kwargs):
        user_id = kwargs.pop('user_id') # Pop out your custom argument
        super(MyForm, self).__init__(args, kwargs) # Initialize your form
                                                   # as usual
        self.user_id = user_id # Add it as an instance variable

Then, in your view:

class CreateVTable(generic.CreateView):
    form_class = MyForm
    model = Vtable

Upvotes: 1

Related Questions