【问题标题】:Django: can't combine Class-based detail and form viewsDjango:无法结合基于类的详细信息和表单视图
【发布时间】:2013-10-03 13:36:02
【问题描述】:

我是 Django 新手,开始使用通常的函数类型视图,但我被要求仅在基于类的视图上执行此操作。 所以有问题。我需要做一个视图,它会做接下来的事情: - 显示一个选定的问题 - 显示该问题的所有答案 - 包含一个表单,允许为此问题添加新答案。

我的models.py:

from datetime import datetime
from django.db import models
from django.contrib.auth.models import User

class Question(models.Model):
    author = models.ForeignKey(User, related_name='questions')
    title = models.CharField(max_length=255)
    text = models.TextField()
    pub_date = models.DateTimeField(auto_now_add=True)
    number_views = models.IntegerField(default=0)
    number_answers = models.IntegerField(default=0)

    def __unicode__(self):
        return self.title

class Answer(models.Model):
    author = models.ForeignKey(User, related_name='answers')
    question = models.ForeignKey("Question", related_name="answers")
    text = models.TextField()
    pub_date = models.DateTimeField(auto_now_add=True)

    def __unicode__(self):
        return self.text

forms.py:

from django import forms
from apps.questions.models import Question, Answer

class QuestionForm(forms.ModelForm):
    class Meta:
        model = Question
        fields = ['title', 'text']

class AnswerForm(forms.ModelForm):
    class Meta:
        model = Answer
        fields = ['text']

views.py 中的代码,我从 django docs 中获取了一些类似的示例,但它不起作用...

class QuestionDetail(DetailView):
    template_name = 'questions/detail.html'
    model = Question

    def get_context_data(self, **kwargs):
        context = super(QuestionDetail, self).get_context_data(**kwargs)
        context['form'] = AnswerForm()
        return context

class AnswerView(FormView, SingleObjectMixin):
    template_name = 'questions/detail.html'
    form_class = AnswerForm
    model = Answer

    def post(self, request, *args, **kwargs):
        if not request.user.is_authenticated():
            return HttpResponseForbidden()
        self.object = self.get_object()
        return super(AnswerView, self).post(request, *args, **kwargs)

    def get_success_url(self):
        return reverse('detail', kwargs={'pk': self.object.pk})

class QuestionDisplay(View):

    def get(self, request, *args, **kwargs):
        view = QuestionDetail.as_view()
        return view(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        view = AnswerView.as_view()
        return view(request, *args, **kwargs)

和 urls.py

urlpatterns = patterns('',
    url(r'^$', views.IndexView.as_view(), name='index'),
    url(r'^(?P<pk>\d+)/$', views.QuestionDisplay.as_view(), name='detail'),
)

此代码显示所选问题和相关答案的详细信息。但是当我在表单中输入一些新答案并单击提交时,它只会返回一个错误“找不到页面”,没有任何回溯或其他内容,并带有指向相同 URL 的链接,其中存储了问题详细信息和答案表单。


问题解决了:

class QuestionDetail(DetailView, ModelFormMixin, ProcessFormView):
    template_name = 'questions/detail.html'
    model = Question
    form_class = AnswerForm

    def get_success_url(self):
        return reverse('questions:detail', kwargs={'pk':self.get_object().id})

    def get_context_data(self, **kwargs):
        context = super(QuestionDetail, self).get_context_data(**kwargs)
        context['form'] = self.form_class
        return context

    def post(self, request, *args, **kwargs):
        self.object = Answer(author=request.user, question=self.get_object())
        return super(QuestionDetail, self).post(request, *args, **kwargs)

url(r'^(?P<pk>\d+)/$', views.QuestionDetail.as_view(), name='detail'),

在 urls.py 中

【问题讨论】:

  • 什么不起作用?您对哪一部分理解有困难?
  • 嗯,这段代码显示了所选问题和相关答案的详细信息。但是当我在表单中输入一些新答案并单击提交时,它只会返回一个错误“找不到页面”,其中包含指向相同 URL 的链接,其中存储了问题详细信息和答案表单。
  • 您需要inline formsets,以及CreateView,然后加载选定问题的表单;这将使用现有答案填充子表单,并为新答案添加一个附加(空)表单

标签: django django-class-based-views


【解决方案1】:

实际上,您的解决方案有两种替代方法可以避免覆盖post 方法:

一种是使用DetailView 并在上下文中添加一个表单。但是,在模板中,您需要为表单标签实际指定action 属性,使用相同的表单指向单独的FormView。这与您的解决方案类似,但有一个单独的FormView,如有必要,可以单独使用。

另一个是使用FormView,它也将包含Question 对象,基于URL 参数。您可以使用该对象来显示其内容、填充表单的字段等等。

【讨论】:

    猜你喜欢
    • 2011-12-11
    • 2013-12-13
    • 2016-04-14
    • 1970-01-01
    • 2010-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多