2015-09-17 2 views
0

Я пишу классное представление, которое позволяет сотрудникам настраивать свой профиль. Поскольку модель сотрудника имеет несколько полей внешнего ключа (например, работодатель является ключевой моделью, использующей ключевую ссылку для компании), я решил не использовать ModelForm и использовать старые добрые формы, чтобы пользователь мог ввести имя компании, в которой они работают, а не 32 .Django: __init __() получил неожиданный аргумент ключевого слова 'first_name'

Вот мой код:

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?

+0

Пожалуйста, покажите вашу модель 'Employee', показать полный' AdminSetting' вида и формы, что вы предоставили в form_class этой точки зрения , Также покажите свой метод save из формы Employee_ProfileSetting. – GwynBleidD

ответ

0

Конструктор модели не может принимать какие-либо аргументы, которые имеют нет соответствующего поля внутри модели. Поэтому, если вы попытаетесь передать first_name в модель, которая не имеет поля first_name, вы получите это исключение.

Чтобы сделать это правильно, добавьте POST данные и возьмите только то, что вам нужно. Также вы можете пройти commit=False в ModelForm.save метод, поэтому созданный объект не будет сохранен. Таким образом, вы можете передать некоторые дополнительные данные, например Employee_ProfileSettings ID может быть перед тем, как сохранить его, перейдите в Employee.

+0

Спасибо за ответ! Тем не менее, я не использую модель ни ModelForm, я использую форму. Если вы можете подумать о способе использования ModelForm для достижения того, что мне нужно, пожалуйста, немного расширьте его.Метод __init__ должен только инициализировать форму, чтобы впоследствии использовать {% для поля в форме%} {{field}} в шаблоне. В своей записке об использовании mutiple-форм и использовании их вы можете уточнить, как это сделать? – EarlyCoder

+0

Я просто понял, что вы используете классные представления. Почему вы не используете реализацию по умолчанию FormView с переписанием 'is_valid'? Кроме того, почему вы вызываете конструктор формы в form_valid? Если вы это делаете, вы, возможно, должны начать его с пост-данных, как и в обычной форме. И если 'Employee_ProfileSetting' является нормальной формой, а не формой модели, почему вы называете ее методом сохранения? Слишком много вопросов о вашем коде прямо сейчас, чтобы опубликовать полный ответ. – GwynBleidD

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) 

Так что словарь экземпляр не расширен.

Наконец, я не думаю, что я понял, почему вы не можете использовать типовую форму ...

+0

Ну, вы не можете использовать ModelForm, поскольку, учитывая, что форма содержит внешний ключ, ссылающийся на модель компании, и учитывая, что изначально у вас нет данных в модели компании, ModelForm отобразит выбранный виджет без опции для выбора. Поэтому я подумал, почему бы не создать форму с кучей полей, получить эти данные и сохранить их в своих соответствующих моделях, настроив функцию сохранения. – EarlyCoder

+0

Одним из решений было бы иметь ModelForm и исключить поле Company, как это: https://docs.djangoproject.com/en/1.8/topics/forms/modelforms/#selecting-the-fields-to-use Затем вы можете добавить новое поле, чтобы ввести компанию в текст (company_text), добавив validate_company_text и переопределить метод init и save, чтобы заполнить реальное поле компании. – Dric512

Смежные вопросы