2013-04-04 105 views
1

我有两个模型,即时通讯做一个自定义表单,以便我可以查看和保存表单从我的HTML到数据库。但是当我尝试保存时,我得到这个错误。Django错误:ValueError

回溯

Environment: 


Request Method: POST 
Request URL: http://127.0.0.1:8008/ 

Django Version: 1.4 
Python Version: 2.7.3 
Installed Applications: 
('django.contrib.auth', 
'django.contrib.contenttypes', 
'django.contrib.sessions', 
'django.contrib.sites', 
'django.contrib.messages', 
'django.contrib.staticfiles', 
'SecondBlog.blog', 
'django.contrib.admin', 
'django.contrib.admindocs') 
Installed Middleware: 
('django.middleware.common.CommonMiddleware', 
'django.contrib.sessions.middleware.SessionMiddleware', 
'django.middleware.csrf.CsrfViewMiddleware', 
'django.contrib.auth.middleware.AuthenticationMiddleware', 
'django.contrib.messages.middleware.MessageMiddleware') 


Traceback: 
File "c:\Python27\lib\site-packages\django\core\handlers\base.py" in get_response 
    111.       response = callback(request, *callback_args,  **callback_kwargs) 
File "f:\apt3\SecondBlog\SecondBlog\blog\views.py" in home 
    10.   if form.is_valid(): 
File "c:\Python27\lib\site-packages\django\forms\forms.py" in is_valid 
    124.   return self.is_bound and not bool(self.errors) 
File "c:\Python27\lib\site-packages\django\forms\forms.py" in _get_errors 
    115.    self.full_clean() 
File "c:\Python27\lib\site-packages\django\forms\forms.py" in full_clean 
    272.   self._post_clean() 
File "c:\Python27\lib\site-packages\django\forms\models.py" in _post_clean 
    309.   self.instance = construct_instance(self, self.instance, opts.fields,  opts.exclude) 
File "c:\Python27\lib\site-packages\django\forms\models.py" in construct_instance 
    51.    f.save_form_data(instance, cleaned_data[f.name]) 
File "c:\Python27\lib\site-packages\django\db\models\fields\__init__.py" in save_form_data 
    454.   setattr(instance, self.name, data) 
File "c:\Python27\lib\site-packages\django\db\models\fields\related.py" in __set__ 
    366.         self.field.name,  self.field.rel.to._meta.object_name)) 

Exception Type: ValueError at/
Exception Value: Cannot assign "u'Sasa'": "Book.author" must be a "Author" instance. 

models.py

class Author(models.Model): 
    name = models.CharField(max_length = 30) 


    class Book(models.Model): 
    author = models.ForeignKey(Author) 
    title = models.CharField(max_length = 100) 

    def __unicode__(self): 
     return '%s' % (self.title) 

forms.py

class CustomForm(ModelForm): 
    author = forms.CharField() 
    def save(self, commit=True): 
     author = Author.objects.get_or_create(name=self.cleaned_data['author']) 

     instance = super(CustomForm, self).save(commit=commit) 
     instance.author = author 
     if commit: 
      instance.save() 
     return instance 

    class Meta: 
     model = Book 
     fields = ('author','title',) 

views.py

def home(request): 
    if request.method == 'POST': 
     form = CustomForm(request.POST) 
     if form.is_valid(): 

      print "all validated" 
      form.save() 
      return HttpResponseRedirect('index.html') 
     else: 
      print "failed" 
    else: 
     form = CustomForm() 

    variables = RequestContext(request, {'form' : form}) 
    return render_to_response('index.html', variables) 

非常感谢。

回答

1

我尝试你的代码并做一些测试,不管我做什么我总是会得到那个错误。因为在作者创建之前,该书首先执行导致实例错误。

我修改了您的代码。我删除您的保存方法,并将其更改为现在正在工作的清理方法。

class CustomForm(forms.ModelForm): 
    author = forms.CharField() 

    def clean(self): 
     cleaned_data = super(CustomForm, self).clean() 
     author = cleaned_data.get("author") 

     if not author: 
      raise forms.ValidationError("Please enter an author") 

     data = Author.objects.create(name=author) 

     cleaned_data['author'] = data 

     return cleaned_data 

    class Meta: 
     model = Book 
     fields = ('author','title',) 
+0

凯瑟琳。我改变了它,但它仍然给我同样的错误:( – noobes 2013-04-04 12:38:38

+1

答案更新。 – catherine 2013-04-04 15:08:22

+0

thks一百万@catherine ...你钉了它..jubiii ...多数民众赞成我正在寻找...现在其保存在我的管理员...顺便说一句,如果我有两个模型,并希望它在一个模板或一个模板和一个提交按钮可以使用相同的方法? – noobes 2013-04-04 19:27:11

0

的问题是,它甚至没有让你的代码,将笔者的实例,因为超类的保存方法有其设置使用文本字段,这是在错误发生。

你可以尝试或者使用pop调用超,或与作者实例替换该值之前删除从cleaned_dataauthor值。

编辑例如

def save(self, commit=True): 
    author = Author.objects.get_or_create(name=self.cleaned_data.pop('author')) 

    instance = super(CustomForm, self).save(commit=commit) 
+0

thks @丹尼尔也许我有点更noober 。我已经在超类之前尝试过'author = kwargs.pop('author')',并且我仍然得到相同的错误,并且我也尝试了'instance = Author()'的结果。你意思是。万分感谢。 – noobes 2013-04-04 13:29:09

+0

喜@Daniel THKS快速回复。我已经添加了'pop'但我仍然得到同样的错误.. :(我检查了回溯,它也给一模一样... – noobes 2013-04-04 13:45:09

3

的问题是不是与节约,但表单的验证。基本上,您可以为Book创建一个自定义版本的模型表单,其中有两个字段authortitle。默认情况下,author字段将显示为作者类型的参考浏览窗口小部件。

但是,您对author = forms.CharField()所做的操作是告诉窗体显示简单的文本输入字段,而不是作者参考选择器。当它试图验证这个..好吧,它不能。

你需要做的是过程验证之前author值,你可以在clean()功能,您可以添加到您的CustomForm

def clean(self): 
    self.cleaned_data['author'] = Author.objects.get_or_create(name=self.cleaned_data['author']) 
    return self.cleaned_data 

一个非常类似的问题,这样做是how to change form field in method is_valid()

+0

THKS @马丁您的答复。但之后我我仍然得到同样的错误已经改变了。其实,这是我的一些节目,我有更多的领域,但我不能做保存到数据库所以这就是为什么即时给予一点点领域走通是的,我敢肯定有一些与验证的事但就是无法理解为什么给我这个ValueError异常所有的时间:( – noobes 2013-04-04 14:15:36

+0

是啊,我想这是不是对我而言最好的想法..尝试更新的答案。 – 2013-04-04 14:30:07

+0

THKS一百万@马丁...我的验证是固定的,但我仍然对节能问题.. – noobes 2013-04-04 19:17:42