在Django 1.6和crispy表单中,我试图在用户提交后添加从API调用返回的forum_id_number
。但是,我得到了一个
Exception Value:
'int' object has no attribute 'required'
提交表格后。我已经确认self.fields['forum_id_number'] = response["User"]["Id"]
导致此问题。
class AccountForm(forms.ModelForm):
class Meta:
model = Employee
def __init__(self, *args, **kwargs):
super(AccountForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_class = 'form-horizontal'
self.helper.label_class = 'col-lg-2 control-label'
self.helper.field_class = 'col-lg-4'
self.helper.layout = Layout(
Fieldset('Account Modify',
'irc_name',
'forum_username',
Hidden('user_assigned', '{{ user.pk }}'),
Hidden('forum_id_number', '0'),
),
FormActions(
Submit('submit', 'Submit', css_class='btn-primary')
)
)
def clean_forum_username(self):
data = self.cleaned_data['forum_username']
SLUG = "users/" + data + ".json"
status_code, response = do_request(SLUG)
if status_code != 200:
raise forms.ValidationError("Your username was not"
" found! Please check the"
" the spelling. Also, your"
" forum username is your"
" forum sign in name.")
elif status_code == 200:
self.fields['forum_id_number'] = response["User"]["Id"]
return data
class Employee(models.Model):
user_assigned = models.ForeignKey(settings.AUTH_USER_MODEL,
related_name='r_assigned')
irc_name = models.CharField(max_length="25",
unique=True)
forum_id_number = models.BigIntegerField(unique=True)
forum_username = models.CharField(max_length="50",
unique=True)
def __unicode__(self):
return self.irc_name
答案 0 :(得分:1)
self.fields['forum_id_number']
是forms.Field
子类的实例。它描述了属性self.forum_id_number
。行self.fields['forum_id_number'] = response["User"]["Id"]
将覆盖此字段描述并将其设置为(Big?)Integer
对象的实例。这个实例当然没有属性required
。
为forum_id_number
设置值的“正确”方法是使用self.forum_id_number = response["User"]["Id"]
或self.cleaned_data['forum_id_number'] = response["User"]["Id"]
。
正确是引号,因为在这种情况下,它确实不是正确的方法。无法知道是否已在任何forum_id_number
方法中清除了字段clean_FIELD
,因此您不知道是应该设置self.forum_id_number
还是self.cleaned_data['forum_id_number']
。现在在forum_id_number
的情况下,没有安全问题,但任何使用Firebug或类似内容的人都可以更改user_assigned
的值。通常最好从表单中排除隐藏字段,并在表单的save
方法中设置实例本身的值。当然,您无法在ValidationError
方法中提出save
(嗯,您可以,但它会生成500 Internal Server Error
),因此您必须获取用户ID在clean_forum_username
方法中:
class AccountForm(forms.ModelForm):
....
def clean_forum_username(self):
data = self.cleaned_data['forum_username']
SLUG = "users/" + data + ".json"
status_code, response = do_request(SLUG)
if status_code != 200:
raise forms.ValidationError("Your username was not"
" found! Please check the"
" the spelling. Also, your"
" forum username is your"
" forum sign in name.")
elif status_code == 200:
self.response = response
return data
def save(self, *args, **kwargs):
# self.response should be valid, otherwise a `ValidationError` would've been raised
self.instance.forum_id_number = self.response['User']['Id']
return super(AccountForm, self).save(*args, **kwargs)