在Django管理界面中,可以很好地将新项目动态添加到外键字段,我想使用bootstrap模式为弹出窗口和Ajax进行表单提交和验证。
这是我的用例:
这是添加项目的主要表单。物品有参考和类别。
这是添加新类别的第二种形式。
显示模态并提交表单以添加新类别我没有问题。 相反,问题在于表单验证(如果用户提交空表单),并刷新选择内容以添加新添加的类别。
这是我的代码:
class ItemForm(forms.ModelForm):
ref = forms.CharField(widget=forms.TextInput(attrs={'class':'form-control'}),max_length=255)
category = forms.ModelChoiceField(queryset=ItemCategory.objects.all(), empty_label="(choose from the list)")
class ItemCategoryForm(forms.ModelForm):
category = forms.CharField(
max_length=255,
required=True,
help_text='Add a new category')
def add(request):
if request.method == 'POST':
form = ItemForm(request.POST)
if form.is_valid():
item= Item()
item.ref = form.cleaned_data.get('ref')
item.save()
return redirect('/item_list/')
else:
form = ItemForm()
form1 = ItemCategoryForm()
return render(request, 'item/add.html', {'form': form, 'form1':form1})
def add_category(request):
if request.method == 'POST':
form1 = ItemCategoryForm(request.POST)
if form1.is_valid():
vulnCategory = ItemCategory()
ItemCategory.category = form1.cleaned_data.get('category')
ItemCategory.save()
if request.is_ajax():
#TODO: What Should I redirect
else:
#TODO: What Should I redirect
else:
#TODO: What Sould I do to return errors without reloding the page and to refresh the list of categories
url(r'^add/$', 'add', name='add'),
url(r'^add_category/$', 'add_category', name='add_category'),
我还添加了这个jQuery函数来加载结果
$(".add").click(function () {
$.ajax({
url: '/items/add_category/',
data: $("form").serialize(),
cache: false,
type: 'post',
beforeSend: function () {
$("#add_category .modal-body").html("<div style='text-align: center; padding-top: 1em'><img src='/static/img/loading.gif'></div>");
},
success: function (data) {
$("#add_category .modal-body").html(data);
}
});
});
PS:我知道它可能是重复的,但没有答案让我明白了。
答案 0 :(得分:6)
在我为内联添加项目的相关类别的解决方案之下。
使用相同的表单,网址作为问题并添加
@login_required
def add_category(request):
data = {}
if request.method == 'POST' :
form = ItemCategoryForm(request.POST)
if form.is_valid():
itemCategory= ItemCategory()
itemCategory.name = form.cleaned_data.get('name')
itemCategory.save()
data['new_itemcategory_value'] = itemCategory.name;
data['new_itemcategory_key'] = itemCategory.pk;
data['stat'] = "ok";
return HttpResponse(json.dumps(data), mimetype="application/json")
else:
data['stat'] = "error";
return render(request, 'item/add_category_modal.html', {'form': form})
else:
form = ItemCategoryForm()
return render(request, 'item/add_category_modal.html', {'form': form})
我的解决方案中棘手的部分是将模态和man形式分成两个不同的html文件,并使用jQuery处理添加和选择新项目。
这个Js代码必须包含在两个html文件中:
// This function is for showing the modal
$(function () {
$(".add_category_show_button").click(function () {
$.ajax({
type: 'GET',
url: '/item/add_category/',
data: $("form").serialize(),
cache: false,
success: function (data, status) {
$('#add_category_modal_id').html(data);
$('#add_category_modal_id').modal()
}
});
}); });
// This second function is for submitting the form inside the modal and handling validation
$(function () {
$(".add_category_submit_button").click(function () {
$.ajax({
type: 'POST',
url: '/item/add_category/',
data: $("form").serialize(),
cache: false,
success: function (data, status) {
if (data['stat'] == "ok") {
$('#add_category_modal_id').modal('hide');
$('#add_category_modal_id').children().remove();
$('#id_category')
.append($("<option></option>")
.attr("value", data['new_itemcategory_key'])
.text(data['new_itemcategory_value']))
.val(data['new_itemcategory_key']);
}
else {
$('#add_category_modal_id').html(data);
$('#add_category_modal_id').modal('show');
}
}
});
}); });
答案 1 :(得分:3)
这就是我过去的做法。请注意,这是一个非常简略的版本,并假设它是所有的ajax请求,让您了解自己可以做些什么。你应该能够在这里扩展。
if form.is_valid():
do_form_work()
# Compile a list of lists (or tuples) of the categories
# e.g. [[x.pk, x.name] for x in categories]
categories = get_categories()
json = json.dumps(categories)
return HttpRepsonse(json, {'content_type' : 'application/json'})
else:
# 'template' here is a partial template of just the form
render(self.request, template, context, status=500)
如果表单无效,您可以使用错误&#39;在ajax帖子上捕获500代码的方法,并重新显示包含所有表单错误的表单。这样你就可以保持表单和模态打开,这样用户就可以纠正错误
如果表单有效,您可以获取返回的json并在选择列表中重新构建选项。
答案 2 :(得分:1)
ModelChoiceField验证表单中对象的选择,如果为空,则表单不会验证。您可以使用{{form.non_field_errors}}和{{field.errors}}来调试此操作,以指出表单未经过验证的确切原因。
作为一个建议,当我有一个类似的用例时,我使用了Dajax和Dajaxice,他们为我做了很棒的工作。我使用了ChoiceFields,但它们甚至可以用于ModelChoiceFields。
的示例