如何为其他模板的表单显示和提交编写基于 Django 类的视图?

Posted

技术标签:

【中文标题】如何为其他模板的表单显示和提交编写基于 Django 类的视图?【英文标题】:How to write Django class-based view for form displaying and submission from other template? 【发布时间】:2016-12-05 01:49:33 【问题描述】:

我有一个想要在多个位置显示的 ModelForm。例如,在 ListView 中,在文章列表下方。我可以通过将它放在 ListView 中的get_context_data() 中来做到这一点。我还想在自己的模板中显示表单。

我已经为表单创建了一个视图,但不知道如何实际编写它。

我在我的模型中定义了get_absolute_url()

class Article(models.Model):
    author = models.ForeignKey('auth.User')
    title = models.CharField(max_length=200)
    text = models.TextField()
    categories = models.ManyToManyField(Category)
    city = models.ForeignKey(City)

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse_lazy('article', args=self.id)

表单本身的视图是:

Views.py

class ArticleSubmitView(CreateView):
    model = Article
    form_class = ArticleSubmitForm
    # is initial necessary?
    inital = 'title': '', 'text': '', 'categories': '', 'city': ''
    # success url not necessary because model has get_absolute_url
    # however it does not redirect to the article
    template_name = 'articles/article-submit.html'
    # handle post data from other template/view
    # ???

模板包含表单(ListView 模板也是如此)。

article-submit.html

% extends 'articles/base.html' %
% block article-submit %
    % include 'articles/article-form.html' %
% endblock article-submit %

表单提交到调用CreateView的url:

article-form.html

<form action="% url 'article-submit' %" method="POST">
    % csrf_token %
    % for field in form %
    <!--- etc. --->
    % endfor %
</form>

urls.py

from django.conf.urls import url
from .views import ArticlesView, ArticleSubmitView

urlpatterns = [
    url(r'^$', ArticlesView.as_view(), name='articles'),
    # some urls left out for brevity
    url(r'^article-submit/$', ArticleSubmitView.as_view(), name='article-submit'),
]

但是,表单不会从列表模板提交,也不会从表单模板本身提交。它也不会重定向或显示任何错误消息。

我做错了什么?

Full code is available here.

编辑:

像这样检查表单是否有效表明该表单实际上是无效的:

class ArticleSubmitView(CreateView):
    model = Article
    form_class = ArticleSubmitForm
    # success url not necessary because model has get_absolute_url
    # however it does not redirect to the article
    template_name = 'articles/article-submit.html'
    # handle post data from other template/view
    # ???
    def form_valid(self, form):
        print('form is valid')
    def form_invalid(self, form):
        print('form is invalid')
        print(form.errors)

但是我得到:AttributeError at /article-submit/'ArticleSubmitForm' object has no attribute 'errors'

将表单呈现为 form

时也会发生同样的事情

【问题讨论】:

看起来您正在尝试同时做几件事 - 自定义模板呈现,而不是仅使用来自第三方应用程序的 form MultiModelForm 并从一个 url 提交到另一个。如果您尝试一次执行其中一项而不是一次全部执行,则调试会更容易。如果您尝试在form_invalid 方法中打印form.errors,它可能会显示出问题所在。如果这没有帮助,请尝试尽可能简化您的视图和模板,并首先获得一个简单的示例。 @Alasdair 是的。我刚刚尝试打印 form.errors,并编辑了 OP 以反映这一点。接下来将尝试仅使用 form 。谢谢! 【参考方案1】:

事实证明,我不需要 django-betterforms。一个常规的模型工作得很好。还有其他一些错误。

这是代码。

models.py

class Article(models.Model):
    author = models.ForeignKey('auth.User')
    title = models.CharField(max_length=200)
    text = models.TextField()
    categories = models.ManyToManyField(Category)
    city = models.ForeignKey(City)

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse_lazy('article', kwargs='pk': self.id)

views.py

class ArticleSubmitView(CreateView):
    model = Article
    form_class = ArticleForm
    template_name = 'articles/article-submit.html'

    def form_valid(self, form):
        print('form is valid')
        print(form.data)
        obj = form.save(commit=False)
        obj.author = self.request.user
        obj.save()
        return HttpResponseRedirect(reverse('article', kwargs='pk': obj.id))

网址和模板(大部分)如上所示。

【讨论】:

以上是关于如何为其他模板的表单显示和提交编写基于 Django 类的视图?的主要内容,如果未能解决你的问题,请参考以下文章

如何为访问控制编写 Django 模板标签?

django 如何写表单提交

在 Django 中,如何为“/”和其他基于根的 url 编写 url 模式

Django如何为多个表单创建一个帖子请求。

如何为未登录用户保存重力表单数据

如何为织梦表单添加时间