Я пытаюсь создать динамическую форму, которая предварительно заполняет initial
атрибут определенного поля (title
), когда другое поле (checkin_type
) выбрано из раскрывающегося меню.
Я использую универсальный Django CreateView
a>, и я хотел бы сделать это путем переопределения метода 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)
Вот как выполняется запрос AJAX в шаблоне формы, называемом templates/dashboard/checkin_form.html
в соответствии с соглашением об именах Django (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-недельная проверка». Любые идеи, почему это не работает?
title
в методеpost
формы, а не в коде Javascript. Кроме того, я совершенно уверен, чтоid
было передано, поскольку я проверил его, зайдя в отладчик (в этом примере он имеет значение1
). Проблема заключается в том, чтобы заставить форму перерисовываться желаемым образом. - person Kurt Peek   schedule 01.03.2018