如何动态更新ModelForm的初始值?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何动态更新ModelForm的初始值?相关的知识,希望对你有一定的参考价值。

我正在尝试创建一个动态形式,当从下拉菜单中选择另一个字段(initial)时,该形式预先填充某个字段(title)的checkin_type属性。

我正在使用Django的通用CreateView,而我想要的方法是覆盖视图的post()方法,这样如果它收到一个AJAX请求(由上面的下拉菜单中的jQuery .change()触发,包含选择选项的id),它更新表单的initialtitle属性。

这是我迄今为止尝试过的观点(在views.py中):

from django.views import generic
from .models import CheckIn, CheckInType


class CheckInCreate(generic.CreateView):
    model = CheckIn
    fields = '__all__'

    def post(self, request, *args, **kwargs):
        if request.is_ajax():
            checkin_type = CheckInType.objects.get(pk=request.POST['id'])
            form = self.get_form()
            form['title'].initial = checkin_type.title
            self.object = CheckIn.objects.create(checkin_type=checkin_type)
            return self.render_to_response(self.get_context_data(form=form))
        else:
            return super().post(request, *args, **kwargs)

以下是根据Django的命名约定(templates/dashboard/checkin_form.html是应用程序的名称)在表单的模板中创建AJAX请求的方式,称为dashboard

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/js-cookie@2/src/js.cookie.min.js"></script>
<script>
    $(document).ready(function(){
        var csrftoken = Cookies.get('csrftoken');

        function csrfSafeMethod(method) {
            // these HTTP methods do not require CSRF protection
            return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
        }
        $.ajaxSetup({
            beforeSend: function(xhr, settings) {
                if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                    xhr.setRequestHeader("X-CSRFToken", csrftoken);
                }
            }
        });

        $(".auto-submit").change(function() {
            $.post({
                url: "{% url 'checkin-create' %}",
                data: {id: $(".auto-submit option:selected").val()}
            })
        });
    });
</script>


<form action="" method="post">{% csrf_token %}
    {% for field in form %}
        <div class="{% if field.name == 'checkin_type' %}auto-submit{% endif %}">
            {{ field.errors }}
            {{ field.label_tag }}
            {{ field }}
        </div>
    {% endfor %}
    <input type="submit" value="Send message" />
</form>

以下是相应的模型(在models.py中):

from django.db import models


class CheckInType(models.Model):
    title = models.CharField(blank=True, max_length=255)
    description = models.TextField(blank=True)

    def __str__(self):
        return self.title


class CheckIn(models.Model):
    checkin_type = models.ForeignKey(CheckInType, null=True, on_delete=models.CASCADE)
    title = models.CharField(blank=True, max_length=255)
    description = models.TextField(blank=True)

    notes = models.TextField(blank=True)

    # Scheduling
    requested_date = models.DateField(blank=True, null=True)
    completed_date = models.DateField(blank=True, null=True)

问题是,当我从checkin_type的下拉菜单中选择一个选项时,我看到表单中没有任何变化:

enter image description here

我希望Title字段在此示例中预先填充“1周签到”。任何想法为什么这不起作用?

答案

我认为如果你将form['title'].initial = checkin_type.title改为form.cleaned_data['title'] = checkin_type.title它会有效

以上是关于如何动态更新ModelForm的初始值?的主要内容,如果未能解决你的问题,请参考以下文章

如何在modelform中给出初始值

使用 Django,如何在模板中动态设置 ModelForm 字段值?

更新中带有小部件的 Django Form DateInput:丢失初始值

为动态创建的 Android 片段提供自定义属性值

关于 Django RadioSelect 初始值

如何使用 Ajax 在 Django 中更新 modelForm