【问题标题】:Django - Can't Initialize Selected Radio Button when using ModelChoiceField with RadioSelect WidgetDjango - 使用带有 RadioSelect 小部件的 ModelChoiceField 时无法初始化选定的单选按钮
【发布时间】:2013-12-08 18:42:14
【问题描述】:

我有一个表单,当用户尝试更新现有数据库记录时,我希望使用模型实例中的数据预先填充该表单。呈现表单时,即使模型实例已传递给 ModelForm,也不会预先选择任何单选按钮。在比下面列出的更大的形式中,除了单选按钮之外的所有字段都预先填充了模型实例中的正确数据。如何预先选择正确的单选按钮?

我的模特:

class TicketType(models.Model):
    type = models.CharField(max_length=15, unique=True)

    def __unicode__(self):
        return self.type.title()


class TestTicket(models.Model):
    ticket_type = models.ForeignKey(TicketType, to_field='type')

我的表单

class TestTicketForm(ModelForm):
    ticket_type = ModelChoiceField(TicketType.objects.all(),
                                   widget=RadioSelect,
                                   empty_label=None)
    class Meta:
        model = TestTicket
        fields = ['ticket_type']

我的观点

def test_ticket_update(request, ticket_num=None):

    # initialize an update flag to distinguish between a request 
    # to add a new ticket or an update to an existing ticket.
    update_requested = False
    ticket_instance = None

    if ticket_num:
        # This is a request to update a specific ticket. 
        # Attempt to retrieve the ticket or show a 404 error.
        # If a ticket is retrieved, it is locked for editing 
        # by using 'select_for_update()' to prevent a race condition.
        ticket_instance = get_object_or_404(
              TestTicket.objects.select_for_update(),pk=ticket_num)
        update_requested = True

    if request.method == 'POST':
        form = TestTicketForm(request.POST, instance=ticket_instance)
        if form.is_valid():
            ticket = form.save(commit=False)
            ticket.save()
            return HttpResponseRedirect('/tickets/')
    else:

        if update_requested:
            # This is a requested to update an existing ticket. 
            # Bind the ticket data to a form.
            form = TestTicketForm(instance=ticket_instance)
        else:
            form = TestTicketForm()

    return render(request, 'ticket_tracker/ticket_update.html', 
                  { 'form': form, 'ticket': ticket_instance})

我的模板

{% block content %}
<div class="container">
        <form action="/tickets/test-ticket/{{ ticket.id }}/" method="post">
            {% csrf_token %}
            {{ form.as_p }}

            <div class="form-group">
                <button type="submit">Save</button>
            </div>

        </form>
</div>
{% endblock content %}

【问题讨论】:

  • 我已经更新了我的问题,以澄清我希望在表单呈现时根据模型实例中的数据预先选择正确的单选按钮。单选按钮确实显示了正确的值,但没有被选中。

标签: django django-forms


【解决方案1】:

这似乎是answered here before。在我的模型中,我在创建 ForeignKey 字段时使用了 to_field 参数,但 ModelChoiceField 期望在将“初始”值传递给它时使用 id。在我的示例中,有几个选项可以解决此问题,包括:

  1. 从模型的 ForeignKey 字段中移除 to_field 参数。
  2. 在视图中创建表单实例时,使用模型实例中的字段 id 为字段设置“初始”参数,例如,

    表单 = TestTicketForm(request.POST, 实例=ticket_instance, 初始={'ticket_type': instance.ticket_type.id)
  3. 在表单__init__()方法中设置表单域的初始值。这再次使用模型实例中的字段 id。例如:

    类TestTicketForm(ModelForm): ticket_type = ModelChoiceField(TicketType.objects.all(), 小部件=无线电选择, 空标签=无)
    def __init__(self, *args, **kwargs):
        super(TestTicketForm, self).__init__(*args, **kwargs)
    
        if self.instance is not None:
            self.initial['ticket_type'] = self.instance.ticket_type.id
    

上面的选项 #1 需要在我的数据库中进行架构和数据迁移。选项 #2 和 #3 相似,但我选择了选项 #3,因为它使我的视图代码更清晰。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-30
    • 2011-10-04
    • 2019-10-05
    • 1970-01-01
    • 2016-07-28
    • 2016-10-02
    • 2012-07-18
    • 2012-03-23
    相关资源
    最近更新 更多