Django: Как автозаполнить внешний ключ соответствующим экземпляром класса модели

Работаю над своим первым проектом Django и мог бы воспользоваться некоторой помощью. У меня есть 2 модели (Decisions, Votes), связанные внешним ключом 'decision'. Шаблон vote_list.html показывает пользователю список решений (сгенерированных другими пользователями), которые содержатся в Decisions. Пользователь нажимает на определенное решение и перенаправляется на второй шаблон для голосования по вариантам, относящимся к этому решению. Как мне автоматически заполнить внешний ключ 'decision' в Votes соответствующим экземпляром Decision, чтобы во втором шаблоне, vote_form.html, отображались варианты решения, на которое пользователь нажал? Я предполагаю, что это кодируется в views.py (я прокомментировал попытку ниже, которая не работает), но как это можно сделать? Спасибо!

urls.py

path('vote-list/', views.VoterView.as_view(), name='vote_list'),
path('vote-list/<pk>/vote-form/', views.VoteForm.as_view(), name='vote_form'),

models.py

class Decisions(models.Model):
    custom_user = models.ForeignKey(CustomUser, 
                  default=None, null=True, 
                  on_delete=models.SET_NULL)
    description = models.CharField(default="", 
                  max_length=100, verbose_name="Decision 
                  Summary")

class Votes(models.Model):
    decision = models.ForeignKey(Decisions, 
               default=None, null=True, 
               on_delete=models.SET_NULL)
    vote = models.CharField(default="", max_length=100, 
            verbose_name="Your vote")

views.py

class VoteForm(LoginRequiredMixin, CreateView):
    model = Votes
    form_class = VotingForm
    template_name = 'users/vote_form.html'

    def post(self, request, *args, **kwargs):
        super()
        form = self.form_class(data=request.POST)
        if form.is_valid():
            instance = form.save(commit=False)
        
            # instance.decision = Decisions.description
        
            instance.save()
        return redirect('users:vote_list')    

forms.py

class VotingForm(forms.ModelForm):
    class Meta:
        model = Votes
        fields = ['vote']

vote_list.html

     {% for item in Decisions %}
         <tr>
            <td>{{ item.description }}</td>
            <td><a href="{% url 'users:vote_form' item.id 
                 %}">Vote</a></td>
         </tr>                   
     {% endfor %}    

vote_form.html

     {# trying to display the corresponding 
          decision description here from vote_list.html # }}

     {{ form.vote|as_crispy_field }}

Я думаю, что это может решить вашу проблему:

  1. Добавьте поле decision в форму голосования. В нем будет отображаться опция выбора, для какого решения вам нужно сохранить этот голос. Если вы не хотите разрешать пользователям изменять решение, вы можете пометить поле как отключенное. Смотрите этот вопрос для более подробной информации о том, как это сделать. Другой альтернативой является полное скрытие поля.
class VotingForm(forms.ModelForm):
    class Meta:
        model = Votes
        fields = ['vote', 'decision']
  1. Добавьте начальное значение decision при инстанцировании VotingForm. Это автоматически установит, какое решение будет выбрано при отображении формы.
class VoteForm(LoginRequiredMixin, CreateView):
    model = Votes
    form_class = VotingForm
    template_name = 'users/vote_form.html'

    def get_form_kwargs(self):
        kwargs = super().get_form_kwargs()
        kwargs.update({'initial': {'decision': self.kwargs['pk']}})

        return kwargs

    def post(self, request, *args, **kwargs):
        super()  # BTW, no idea why is this here
        form = self.form_class(data=request.POST)
        if form.is_valid():
            form.save(commit=False)        
        return redirect('users:vote_list')

Кроме того, ваша форма, вероятно, должна отображаться в HTML-шаблоне следующим образом: {% crispy form %}. Таким образом, все определенные поля будут отображаться автоматически.

Вернуться на верх