'str'对象没有'visible_fields'属性; 基于django类的观点

cod*_*321 2 forms django django-class-based-views

我昨天开始一整天都在努力争取课堂观点.我的问题一直在变'str' object has no attribute 'visible_fields',所以下面的'表单'项目实际上不是一个表单:

模板-

<form action="" method="post">
    {% csrf_token %}
    {{form|bootstrap}}
    <input type="submit" name="submit" value="Add new article"/>
</form>
Run Code Online (Sandbox Code Playgroud)

视图-

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')
Run Code Online (Sandbox Code Playgroud)

最糟糕的是印刷type(form)节目<class 'index.forms.ArticleForm'>.如果表单已保存,我正在尝试将其重定向到列表视图,并在表单错误的情况下重播带有错误的表单(您已经有一篇包含该URL的文章).我听说课堂观点更容易使用,而且我通过使用它们读过的大型项目,但它们看起来确实比旧观点更糟糕.我认为这是因为我没有很好地使用它们

我见过的每个例子都有一个模板以某种方式获得"形式",比如

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
Run Code Online (Sandbox Code Playgroud)

然后像魔术一样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'
Run Code Online (Sandbox Code Playgroud)

这种废墟的目的是以阶级为基础的观点.看来我应该通过在表单中​​覆盖"干净"来处理标题?

否则,如何使此视图传递一个表单对象,在模板中呈现它,如果表单没有通过则只重新呈现模板?

我如何访问模板中的表单?

谢谢

Dan*_*man 5

您可以按照示例视图执行此操作,而post不是像您一样覆盖.

在您的情况下,简单地显示和处理表单是CreateView 的默认行为.所以根本不需要覆盖任何方法.您的观点应该是:

class ArticleCreateView(CreateView):
    model = Article
    template_name = 'index/add_article.html'
    form_class = ArticleForm
Run Code Online (Sandbox Code Playgroud)