Представления на основе классов - объединение нескольких моделей с помощью FormView - PullRequest
0 голосов
/ 23 января 2019

Я пытаюсь создать приложение Survey.Я определил модель для опроса, вопросов, ответов, как показано ниже.

Что я хочу сделать, это создать опрос (в режиме администратора, что я могу сделать), а затем отобразить этот опрос в виде страницы, которую пользователи могут заполнять.

Я впервые использую представления на основе классов, и я застрял в том, как визуализировать форму Survey вместе со связанными вопросами и разрешить ввод ответов.

В Admin,Я создал опрос и успешно добавил в него Вопросы.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)

URLS

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__'

1 Ответ

0 голосов
/ 23 января 2019

Хорошо, способ сделать это - использовать FormSets . Они немного ошибочны в настройке, но не должны занимать у вас много времени. Я рекомендую использовать эту маленькую библиотеку js, чтобы помочь .

Я также переписал часть вашего кода, чтобы, надеюсь, немного облегчить вам жизнь:

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__'
...