Как отобразить ВЫБОРЫ в Django ModelForm - PullRequest
1 голос
/ 16 октября 2019
  • У меня есть модель policy_category с 16 категориями.
  • У меня есть модель Response для записи ответов на опрос. Модель включает поле для записи рейтинга респондента 1-5 для каждой из категорий политики. (policy_1_rank..policy_16_rank и т. 1011 *
     <div><b>How important are each of the following issues or policy areas to you, when you're selecting a candidate for president?</b></div>
    <div><br></div>
    <ul><div>{{ policy_category.object(pk=1) }}</div></ul>
    # show POLICY_1_CHOICES below:
    <div>{{ form.policy_1_rank }}</div>
    
    <div><br></div>
    <ul><div>{{ policy_category.object(pk=2) }}</div></ul>
    # show POLICY_2_CHOICES below:
    <div>{{ form.policy_2_rank }}</div>
    ...
    

    Модель ответов:

    # Temp Survey Response
    class Temporaryresponse(models.Model):
        # Healthcare
        POLICY_1_CHOICES = [
        (1, '1: Extremely supportive of a healthcare system with ONLY private insurance'),
        (2, '2: Somewhat supportive of a healthcare system with ONLY private insurance'),
        (3, '3: Somewhat supportive of a healthcare system with BOTH private insurance and a public insurance option'),
        (4, '4: Extremely supportive of a healthcare system with BOTH private insurance and a public insurance option'),
        (5, '5: Somewhat supportive of a healthcare system with ONLY public insurance (commonly referred to as "universal healthcare")'),
        (6, '6: Extremely supportive of a healthcare system with ONLY public insurance (commonly referred to as "universal healthcare")'),
    ]
    ...
    # Healthcare
        policy_1_rank = models.IntegerField(blank=True, default=0, choices=POLICY_1_CHOICES)
    

    Forms.py

    class NextresponseForm(ModelForm):
        policy_1_rank = forms.IntegerField()
        policy_2_rank = forms.IntegerField()
    ...
    
    class Meta:
            model = Temporaryresponse
            fields = ['policy_1_rank', 'policy_2_rank',...]
    

    РЕДАКТИРОВАТЬ: Может быть, ответ ниже не работает, потому что есть проблема с моей точки зрения. Я пытаюсь перейти с первой страницы формы «tr.html», сохранить данные и отправить pk ответа «nr.html» для второй части опроса. Это работаетНо неверно ли мое представление о "nr.html"?

    views.py

    # Create temporary response view - this saves and goes to nr perfectly. pk produced from saving the response shows in nr link in web browser (myapp/nr/pk# shows here perfectly.)
    def tr(request):
        if request.method == "POST":
            form = TemporaryresponseForm(request.POST)
            if form.is_valid():
                tempresponse = form.save()
                tempresponse.save()
                return redirect('nr', pk=tempresponse.pk)
        else:
            form = TemporaryresponseForm()
        return render(request, 'politicalexperimentpollapp/tr.html', {'form': form})
    
    
    def nr(request, pk):
        tempresponse = get_object_or_404(Temporaryresponse, pk=pk)
        instance = Temporaryresponse.objects.get(pk=pk)
        if request.method == "POST":
            form = NextresponseForm(request.POST, instance=instance)
            if form.is_valid():
                nextresponse = form.save()
                nextresponse.save()
                return redirect('fr', pk=nextresponse.pk)
        else:
            form = NextresponseForm(instance=instance)
        return render(request, 'politicalexperimentpollapp/nr.html', {'tempresponse': tempresponse}, {'form': form})
    

1 Ответ

0 голосов
/ 16 октября 2019

Вы можете переопределить поля вашей формы в __init__, чтобы включить forms.ChoiceField:

class NextresponseForm(ModelForm):  
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['policy_1_rank'] = forms.ChoiceField(
            choices=self._meta.model.POLICY_1_CHOICES)

    class Meta:
            model = Temporaryresponse
            fields = ['policy_1_rank', 'policy_2_rank',...]

Обновление

Самый простой способ визуализации объекта формыв Django это передать его как контекст в вашем представлении:

def some_view(request):
    form = NextresponseForm(request.POST or None)
    context = {'form':form}
    return render(request, 'some_template.html', context)

Затем вы можете получить доступ к форме, позвонив form.as_ul в вашем шаблоне:

<ul>
{{ form.as_ul }}
</ul>

Обновление 2

Последняя строка в ваших представлениях неверна:

return render(request, 'politicalexperimentpollapp/nr.html', {'tempresponse': tempresponse}, {'form': form})

Вместо этого должно быть:

return render(request, 'politicalexperimentpollapp/nr.html', {'tempresponse': tempresponse, 'form': form})

context - это словарь . Если вам нужно передать несколько элементов в шаблон, вам нужно включить в контекстный словарь несколько ключей, а не несколько аргументов.

Наконец, я бы рекомендовал всегда инициализировать формы с помощью request.POST or None, чтобы не сделать вашу форму недействительной:

    form = TemporaryresponseForm(request.POST or None)

Это ответ из учебника на часто задаваемый вопрос «Почему form.is_valid() всегда недействителен?» .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...