如何动态更新ModelForm的初始值?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何动态更新ModelForm的初始值?相关的知识,希望对你有一定的参考价值。
我正在尝试创建一个动态形式,当从下拉菜单中选择另一个字段(initial
)时,该形式预先填充某个字段(title
)的checkin_type
属性。
我正在使用Django的通用CreateView
,而我想要的方法是覆盖视图的post()
方法,这样如果它收到一个AJAX请求(由上面的下拉菜单中的jQuery .change()
触发,包含选择选项的id
),它更新表单的initial
的title
属性。
这是我迄今为止尝试过的观点(在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
的下拉菜单中选择一个选项时,我看到表单中没有任何变化:
我希望Title
字段在此示例中预先填充“1周签到”。任何想法为什么这不起作用?
答案
我认为如果你将form['title'].initial = checkin_type.title
改为form.cleaned_data['title'] = checkin_type.title
它会有效
以上是关于如何动态更新ModelForm的初始值?的主要内容,如果未能解决你的问题,请参考以下文章
使用 Django,如何在模板中动态设置 ModelForm 字段值?