Django:__ init __()得到了一个意外的关键字参数'first_name'

时间:2015-09-17 13:50:42

标签: django django-forms

我正在编写一个基于类的视图,让员工可以设置他们的个人资料。因为员工模型有一些外键字段(例如雇主是一个forieng键引用公司模型),所以我决定不使用ModelForm并使用好的旧表单,这样用户就可以输入他们工作的公司名称而不是32

这是我的代码:

class Employee_ProfileSetting(forms.Form):
    first_name = forms.CharField(label = 'First Name', max_length = 30)
    last_name = forms.CharField(label = 'Last Name', max_length = 30)
    email = forms.EmailField()
    employer = forms.CharField(max_length = 50)
    cell = forms.CharField(max_length = 20)
    driver_license_num = forms.CharField(max_length=20)
    birth_year = forms.IntegerField()
    start_date = forms.IntegerField(help_text = 'Year you started with the company')
    title = forms.CharField(max_length = 30)

    def __init__(self, *args, **kwargs):

        if not args: # args is empty, meaning a fresh object            
            super(Employee_ProfileSetting, self).__init__(*args, **kwargs)

        else:
            # Retrieving the form's information
            self.first_name = args[0].get('first_name')
            self.last_name = args[0]['last_name']
            self.email = args[0]['email']
            self.cell = args[0]['cell']
            self.driver_license_num = args[0]['driver_license_num']
            self.birth_year = args[0]['birth_year']
            self.start_year = args[0]['start_date']
            self.title = args[0]['title']

            super(Employee_ProfileSetting, self).__init__(*args, **kwargs)

然后构造函数允许我在基于类的视图中执行此操作:

# Inside class AdminSetting(View):  
def post(self, request):
    form = self.form_class(request.POST)

    if form.is_valid():
        cd = form.cleaned_data
        employee_profile = Employee_ProfileSetting(**cd) # Calling the constructor
        employee_profile.save()  # The save function is overridden


        admin, created = Employee.objects.get_or_create(**cd)  # If a matching employee exists, it gets that object.  Otherwise, it creates it.

        if created:  # Object was not found, and so it was created
            return HttpResponseRedirect('success.html')

当我运行它时,它会给我错误:

__ init __()得到了一个意外的关键字参数'first_name'

所以,我的问题是双重的:

1)代码有什么问题?这个错误意味着什么?

2)是否有更好的方法让用户在表单中填写所有字段,包括外键字段,并相应地保存字段?例如对应于外键的字段首先保存在其各自的表中(company1.employee_set.create(),然后保存其他字段。可以使用ModelForm吗?

2 个答案:

答案 0 :(得分:0)

模型的构造函数不能接受模型中没有匹配字段的任何参数。因此,如果您尝试将first_name传递给没有first_name字段的模型,您将获得该异常。

要正确执行此操作,您可以创建多个表单并使用它们。表单应忽略额外的POST数据,并仅采用它所需的内容。您也可以将commit=False传递给ModelForm.save方法,这样创建的对象就不会被保存。这样您就可以传递一些其他数据,例如Employee_ProfileSettings ID可以在保存之前传递到Employee

答案 1 :(得分:0)

你定义init的方式很奇怪。它应该是这样的:

def __init__(self, data, *args, **kwargs):

    if not data: # data is empty, meaning a fresh object            
        super(Employee_ProfileSetting, self).__init__(*args, **kwargs)

    else:
        # Retrieving the form's information
        self.first_name = data[0].get('first_name')
        self.last_name = data[0]['last_name']
        self.email = data[0]['email']
        self.cell = data[0]['cell']
        self.driver_license_num = data[0]['driver_license_num']
        self.birth_year = data[0]['birth_year']
        self.start_year = data[0]['start_date']
        self.title = data[0]['title']

        super(Employee_ProfileSetting, self).__init__(*args, **kwargs)

第二件事是你怎么称呼你上课:

employee_profile = Employee_ProfileSetting(**cd)    

扩展了所有clean_data列表。这扩展到:

employee_profile = Employee_ProfileSetting(first_name=cleaned_data[first_name], ...)

相反,你应该这样称呼它:

employee_profile = Employee_ProfileSetting(form.cleaned_data)

这样就不会扩展字典实例。

最后,我不认为我理解为什么你不能使用模型表格......