如何编写基于 Django class 的视图来显示和提交来自其他模板的表单?
How to write Django class-based view for form displaying and submission from other template?
我有一个 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'),
]
但是,表单不从列表模板提交,也不从表单模板本身提交。它也不会重定向或显示任何错误消息。
我做错了什么?
编辑:
像这样检查表格是否有效表明表格实际上是无效的:
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 }}时会发生同样的事情
事实证明,我不需要 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}))
网址和模板(大部分)与上述相同。
我有一个 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'),
]
但是,表单不从列表模板提交,也不从表单模板本身提交。它也不会重定向或显示任何错误消息。
我做错了什么?
编辑:
像这样检查表格是否有效表明表格实际上是无效的:
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 }}时会发生同样的事情
事实证明,我不需要 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}))
网址和模板(大部分)与上述相同。