【问题标题】:Class-based-views - Pulling together multiple models using FormView基于类的视图 - 使用 FormView 将多个模型组合在一起
【发布时间】:2019-01-23 11:43:32
【问题描述】:

我正在尝试构建一个调查应用程序。我为调查、问题、响应定义了一个模型,如下所示。

我想要做的是创建一个调查(在管理员中,我可以这样做)然后将此调查显示为用户可以填写的页面。

我是第一次使用基于类的视图,我不知道如何呈现调查表单以及相关的问题并允许输入答案。

在管理员中,我创建了一个调查并成功向其中添加了问题。 FormView(和 UpdateView,作为另一个 SO 答案的一部分尝试)允许我显示调查模型的“名称”和“描述”属性 - 但问题不会出现。

我需要做什么才能在我的表单中提供调查及其问题(并允许用户输入回复)?

模型

class Survey(models.Model):
    name = models.CharField(max_length=400)
    description = models.TextField()

    def survey_questions(self):
        if self.pk:
            return Question.objects.filter(survey=self.pk)
        else:
            return None

    def publish(self):
        self.published_date = timezone.now()
        self.save()

class Question(models.Model):
    survey = models.ForeignKey(Survey, on_delete=models.CASCADE)
    question = models.TextField()

class Response(models.Model):
    member = models.ForeignKey(user_model, on_delete=models.SET_NULL, null=True, blank=True)
    survey = models.ForeignKey(Survey, on_delete=models.CASCADE)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now_add=True)

class AnswerBase(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    response = models.ForeignKey(Response, on_delete=models.CASCADE)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

class AnswerText(AnswerBase):
    body = models.TextField(blank=True, null=True)

网址

urlpatterns = [path('survey/<int:pk>/', views.SurveyResponseView.as_view(), name='survey_detail')]

观看次数

class SurveyResponseView(FormView):
    template_name = 'survey/survey_detail.html'
    form_class = ResponseForm

表格

class ResponseForm(forms.ModelForm):

    class Meta():
        model = Survey
        fields = '__all__'

【问题讨论】:

    标签: django forms django-class-based-views


    【解决方案1】:

    好的,这样做的方法是使用FormSets。设置它们有点麻烦,但不应该花太长时间。我推荐使用this small js library to help

    我还重写了您的一些代码,希望能让您的生活更轻松:

    models.py

    class SurveyTemplate(models.Model):
        name = models.CharField(max_length=400)
        description = models.TextField()
        # You were missing this I believe
        published_date = models.DateTimeField(blank=True, null=True)
    
        def publish(self):
            self.published_date = timezone.now()
            self.save()
    
    
    class Question(models.Model):
        # Now you can do SurveyTemplate.questions.all()
        survey = models.ForeignKey(Survey, on_delete=models.CASCADE, related_name='questions')
        question = models.TextField()
    
    
    class SurveyResponse(models.Model):
        member = models.ForeignKey(user_model, on_delete=models.SET_NULL, null=True, blank=True)
        survey = models.ForeignKey(Survey, on_delete=models.CASCADE)
        created = models.DateTimeField(auto_now_add=True)
        updated = models.DateTimeField(auto_now_add=True)
    
    
    class Answer(models.Model):
        # Now you can do Question.answers.all()
        question = models.ForeignKey(Question, on_delete=models.CASCADE, related_name='answers')
        # Now you can do Response.answers.all()
        response = models.ForeignKey(Response, on_delete=models.CASCADE, related_name='answers')
        created = models.DateTimeField(auto_now_add=True)
        updated = models.DateTimeField(auto_now=True)
    

    views.py

    from django.views.generic import CreateView
    
    
    # CreateView is Django's built in View for creating an object, you would be best to use it
    class SurveyResponseView(CreateView):
        model = Survey
        template = 'survey/survey_detail.html'
        form_class = ResponseForm
    

    forms.py

    class ResponseForm(forms.ModelForm):
        class Meta():
            model = Survey
            fields = '__all__'
    

    【讨论】:

    • 我目前正在查看 FormSets,所以也许我还没有看到全貌,但是您确定“CreateView”(对于SurveyResponseView)是正确的通用视图吗?当我点击填写ResponseForm(127.0.01/survey/0)时,可以看到属于Survey模型的字段(namedescriptionpublished_date)。我希望用户填写 Answer 字段而不是 Survey 字段。我假设我稍后将禁用Survey 字段的编辑,并通过FormSets 显示QuestionsAnswers,对吗?只是想确定一下 - CBV 有点令人困惑
    • 是的,因此您需要使用表单集将各种答案对象添加到视图中。你有没有实现过这样的东西:medium.com/@taranjeet/…他的指南很好。
    猜你喜欢
    • 2013-05-01
    • 2012-10-09
    • 2020-08-09
    • 1970-01-01
    • 1970-01-01
    • 2012-04-02
    • 2018-02-18
    • 2018-11-25
    • 1970-01-01
    相关资源
    最近更新 更多