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

发布于 2025-01-15 10:28:55 字数 2226 浏览 1 评论 0原文

正在开发我的第一个 Django 项目,需要一些帮助。我有两个模型(决策、投票)通过称为“决策”的外键链接。模板 vote_list.html 向用户显示决策中包含的决策列表(由其他用户生成)。用户点击特定决策,然后被重定向到第二个模板,以对与该决策相关的选项进行投票。如何使用相应的决策实例自动填充投票中的外键“决策”,以便第二个模板 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")

视图

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

.py 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 }}

Working on my first Django project and could use some help. I have 2 models (Decisions, Votes) linked by the foreign key called 'decision'. The template, vote_list.html, shows the user a list of decisions (generated by other users) that are contained in Decisions. The user taps a particular decision and is re-directed to a second template to vote on options pertaining to that decision. How do I autopopulate the foreign key 'decision' in Votes with the corresponding instance of Decision so that the second template, vote_form.html, displays the options for the decision they tapped on? I assume it's coded in views.py (I commented an attempt below that doesn't work), but how might it be done? Thank you!

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 }}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一个人的旅程 2025-01-22 10:28:55

我认为这可能会解决您的问题:

  1. 在投票表单中添加 decision 字段。这将显示一个选项,用于选择您需要保存此投票的决定。
    如果您不想允许用户更改决策,您可以将该字段标记为禁用。有关更多详细信息,请参阅此问题关于如何做到这一点。另一种选择是完全隐藏该字段。
class VotingForm(forms.ModelForm):
    class Meta:
        model = Votes
        fields = ['vote', 'decision']
  1. 实例化 VotingForm 时添加 decision 的初始值。这将自动设置显示表单时选择的决策。
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 类中所有定义的字段都会自动呈现。

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

I think this might solve your problem:

  1. Add decision field in the voting form. This will display an option to select for which decision you need to save this Vote for.
    If you don't want to allow users to change the Decision, you can mark the field as disabled. See this issue for more details on how to do that. Another alternative is to completely hide the field.
class VotingForm(forms.ModelForm):
    class Meta:
        model = Votes
        fields = ['vote', 'decision']
  1. Add initial value of the decision when instantiating the VotingForm. This will automatically set which decision is selected when displaying the form.
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')

Also, your form should probably be displayed like this in the HTML template: {% crispy form %}. This way all defined fields from the VotingForm class are rendered automatically.

<form method="post" action="{% url 'users:vote_form' pk %}">
     {% crispy form %}
</form>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文