Class-based-views - 使用 FormView 将多个模型组合在一起
Class-based-views - Pulling together multiple models using FormView
我正在尝试构建一个调查应用程序。我已经为调查、问题、响应定义了一个模型,如下所示。
我想做的是创建一个调查(在管理员中,我可以做)然后将此调查显示为用户可以填写的页面。
我是第一次使用 Class 基于视图,我对如何呈现调查表单以及相关问题并允许输入答案感到困惑。
在管理员中,我创建了一个调查并成功地向其中添加了问题。 FormView(和 UpdateView,尝试作为另一个 SO 答案的一部分)允许我显示 Survey 模型的 'name' 和 'description' 属性 - 但问题没有出现。
我需要做什么才能使调查及其问题在我的表单中可用(并允许用户输入回复)?
型号
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__'
好的,方法是使用 FormSets. They're a bit of a faff to setup, but shouldn't take you too long. I recommend using 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__'
我正在尝试构建一个调查应用程序。我已经为调查、问题、响应定义了一个模型,如下所示。
我想做的是创建一个调查(在管理员中,我可以做)然后将此调查显示为用户可以填写的页面。
我是第一次使用 Class 基于视图,我对如何呈现调查表单以及相关问题并允许输入答案感到困惑。
在管理员中,我创建了一个调查并成功地向其中添加了问题。 FormView(和 UpdateView,尝试作为另一个 SO 答案的一部分)允许我显示 Survey 模型的 'name' 和 'description' 属性 - 但问题没有出现。
我需要做什么才能使调查及其问题在我的表单中可用(并允许用户输入回复)?
型号
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__'
好的,方法是使用 FormSets. They're a bit of a faff to setup, but shouldn't take you too long. I recommend using 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__'