'str' object 没有属性 'visible_fields';基于 django class 的视图
'str' object has no attribute 'visible_fields'; django class based views
自从昨天开始观看以来,我一整天都在为 class 观看而苦苦挣扎。我的问题是不断 'str' object has no attribute 'visible_fields'
,所以下面的 'form' 项并不是真正的形式:
模板-
<form action="" method="post">
{% csrf_token %}
{{form|bootstrap}}
<input type="submit" name="submit" value="Add new article"/>
</form>
查看-
class ArticleCreateView(CreateView):
model = Article
template_name = 'index/add_article.html'
form_class = ArticleForm
def post(self, request, *args, **kwargs):
article_form = self.get_form()
if article_form.is_valid():
article = article_form.save(commit=False)
title = article_form.cleaned_data['title']
url = article_form.cleaned_data['url']
title = process_title(url)
article.title = title
article.save()
return redirect("index:article_list")
else:
form = ArticleForm()
print type(form)
print dir(self)
return render(request, 'index/add_article.html')
最糟糕的部分是打印 type(form)
显示它是 <class 'index.forms.ArticleForm'>
。如果表单已保存,我试图让它重定向到列表视图,如果表单不好,我会重播带有错误的表单(您已经有一篇文章 URL)。我听说 class 视图更易于使用,而且我通读过的大型项目都在使用它们,但它们看起来确实比旧视图更糟糕。我想那是因为我没有很好地使用它们
我见过的每个示例都有一个模板以某种方式获得 "form",例如
class RangeCreateView(CreateView):
model = Range
template_name = 'dashboard/ranges/range_form.html'
form_class = RangeForm
def get_success_url(self):
if 'action' in self.request.POST:
return reverse('dashboard:range-products',
kwargs={'pk': self.object.id})
else:
msg = render_to_string(
'dashboard/ranges/messages/range_saved.html',
{'range': self.object})
messages.success(self.request, msg, extra_tags='safe noicon')
return reverse('dashboard:range-list')
def get_context_data(self, **kwargs):
ctx = super(RangeCreateView, self).get_context_data(**kwargs)
ctx['title'] = _("Create range")
return ctx
然后在 range_form.html
中施展魔法:
{% include "dashboard/partials/form_fields.html" with form=form %}
我的问题是我需要处理表单的标题,
def process_title(url):
def _search_for_title(url):
try:
r = requests.get(url)
content = r.text
t = html.document_fromstring(content)
return t.find(".//title").text
except IOError:
return None
title = _search_for_title(url)
return title or 'None'
这种破坏了基于 class 的视图的目的。看来我应该通过覆盖表单本身的 'clean' 来处理标题?
否则,我怎样才能让这个视图通过表单 object,在模板中呈现它,如果表单没有通过,就只 re-render 模板?
以及如何访问模板中的表单?
谢谢
您可以按照示例视图进行操作,而不是像您正在做的那样覆盖 post
。
在您的情况下,简单地显示和处理表单是 CreateView 的默认行为。所以根本不需要覆盖任何方法。您的观点应该是:
class ArticleCreateView(CreateView):
model = Article
template_name = 'index/add_article.html'
form_class = ArticleForm
自从昨天开始观看以来,我一整天都在为 class 观看而苦苦挣扎。我的问题是不断 'str' object has no attribute 'visible_fields'
,所以下面的 'form' 项并不是真正的形式:
模板-
<form action="" method="post">
{% csrf_token %}
{{form|bootstrap}}
<input type="submit" name="submit" value="Add new article"/>
</form>
查看-
class ArticleCreateView(CreateView):
model = Article
template_name = 'index/add_article.html'
form_class = ArticleForm
def post(self, request, *args, **kwargs):
article_form = self.get_form()
if article_form.is_valid():
article = article_form.save(commit=False)
title = article_form.cleaned_data['title']
url = article_form.cleaned_data['url']
title = process_title(url)
article.title = title
article.save()
return redirect("index:article_list")
else:
form = ArticleForm()
print type(form)
print dir(self)
return render(request, 'index/add_article.html')
最糟糕的部分是打印 type(form)
显示它是 <class 'index.forms.ArticleForm'>
。如果表单已保存,我试图让它重定向到列表视图,如果表单不好,我会重播带有错误的表单(您已经有一篇文章 URL)。我听说 class 视图更易于使用,而且我通读过的大型项目都在使用它们,但它们看起来确实比旧视图更糟糕。我想那是因为我没有很好地使用它们
我见过的每个示例都有一个模板以某种方式获得 "form",例如
class RangeCreateView(CreateView):
model = Range
template_name = 'dashboard/ranges/range_form.html'
form_class = RangeForm
def get_success_url(self):
if 'action' in self.request.POST:
return reverse('dashboard:range-products',
kwargs={'pk': self.object.id})
else:
msg = render_to_string(
'dashboard/ranges/messages/range_saved.html',
{'range': self.object})
messages.success(self.request, msg, extra_tags='safe noicon')
return reverse('dashboard:range-list')
def get_context_data(self, **kwargs):
ctx = super(RangeCreateView, self).get_context_data(**kwargs)
ctx['title'] = _("Create range")
return ctx
然后在 range_form.html
中施展魔法:
{% include "dashboard/partials/form_fields.html" with form=form %}
我的问题是我需要处理表单的标题,
def process_title(url):
def _search_for_title(url):
try:
r = requests.get(url)
content = r.text
t = html.document_fromstring(content)
return t.find(".//title").text
except IOError:
return None
title = _search_for_title(url)
return title or 'None'
这种破坏了基于 class 的视图的目的。看来我应该通过覆盖表单本身的 'clean' 来处理标题?
否则,我怎样才能让这个视图通过表单 object,在模板中呈现它,如果表单没有通过,就只 re-render 模板?
以及如何访问模板中的表单?
谢谢
您可以按照示例视图进行操作,而不是像您正在做的那样覆盖 post
。
在您的情况下,简单地显示和处理表单是 CreateView 的默认行为。所以根本不需要覆盖任何方法。您的观点应该是:
class ArticleCreateView(CreateView):
model = Article
template_name = 'index/add_article.html'
form_class = ArticleForm