Django:如何使用相应的模型 class 实例自动填充外键

Django: How to autopopulate foreign key with the corresponding model class instance

正在处理我的第一个 Django 项目,需要一些帮助。我有 2 个模型(决策、投票)由名为 '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 字段。这将显示 select 的选项,您需要为其保存此投票的决定。 如果您不想让用户更改决策,您可以将该字段标记为禁用。有关如何执行此操作的更多详细信息,请参阅 this issue。另一种选择是完全隐藏该字段。
class VotingForm(forms.ModelForm):
    class Meta:
        model = Votes
        fields = ['vote', 'decision']
  1. 实例化VotingForm时添加decision的初始值。这将自动设置在显示表单时 selected 哪个决定。
class VoteForm(LoginRequiredMixin, CreateView):
    model = Votes
    form_class = VotingForm
    template_name = 'users/vote_form.html'

    # Use this to pass 'pk' to your context in the template
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context.update({'pk': self.kwargs['pk'})

        return context

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

        return initial

    def get_success_url():
        # Import reverse from django.urls
        return reverse('users:vote_list')

此外,您的表单在 HTML 模板中可能应该像这样显示:{% crispy form %}。这样,VotingForm class 中的所有定义字段都会自动呈现。

<form method="post" action="{% url 'users:vote_form' pk %}">
     {% crispy form %}
</form>