2

私は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

フォーム.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で

4

1 に答える 1

0

実際、postメソッドのオーバーライドを回避するソリューションには、2 つの代替アプローチがあります。

1 つは、a を使用DetailViewしてコンテキストにフォームを追加することです。ただし、テンプレートでは、フォーム タグの属性を実際に指定する必要があり、同じフォームを使用しactionて別のものを指します。FormViewこれはソリューションに似ていますが、FormView必要に応じて個別に使用できる別のものがあります。

もう 1 つは、URL パラメータに基づいてFormView、オブジェクトも含む を使用しています。Questionそのオブジェクトを使用して、その内容を表示したり、フォームのフィールドに入力したりできます。

于 2013-09-27T20:03:37.293 に答える