我有两个型号Publisher
和Book
像下面
models.py
class Publisher(models.Model):
name = models.CharField(max_length=255)
class Book(models.model):
name = models.CharField(max_length=255)
price = models.DecimalField()
generic = generic.GenericForeignKey()
publisher_id = models.PositiveIntegerField()
forms.py
class PublisherForm(ModelForm):
model = Publisher
class BookForm(ModelForm):
model = Book
exclude = ('generic', 'publisher_id',)
def __init__(self, *args, **kwargs):
super(BookForm, self).__init__(*args, **kwargs)
self.fields['name'].widget.attrs = {'id':'inputId', 'class':'input-block-level, 'placeholder':'Name'}
self.fields['name'].error_messages = {'required': 'Please enter name'}
self.fields['age'].widget.attrs = {'id':'inputId', 'class':'input-block-level, 'placeholder':'Age'}
self.fields['age'].error_messages = {'required': 'Please enter age'}
views.py
在这里,在这个观点,我将发送发行商ID,因为Book
模型并没有一个外键发布模型
from .forms import BookForm
@login_required
def create_multiple_books(request, publisher_id):
class RequiredFormSet(BaseFormSet):
def __init__(self, *args, **kwargs):
super(RequiredFormSet, self).__init__(*args, **kwargs)
for form in self.forms:
form.empty_permitted = False
BookFormset = formset_factory(BookForm, max_num=10, formset=RequiredFormSet)
if request.method == 'POST':
book_formset = BookFormset(request.POST, request.FILES)
if book_formset.is_valid():
for form in book_formset.forms:
obj = form.save(commit=False)
obj.publisher_id = publisher_id
obj.save()
return redirect(reverse('created'))
else:
book_formset = BookFormset()
c = {'book_formset': book_formset,
'publisher_id':publisher_id,
}
c.update(csrf(request))
return render_to_response('add_books.html',c,context_instance = RequestContext(request))
template.html
因此,在下面的模板呈现的形式form.as_p
它的做工精细和多个记录创建到publisher id
成功
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
// Code adapted from http://djangosnippets.org/snippets/1389/
function updateElementIndex(el, prefix, ndx) {
var id_regex = new RegExp('(' + prefix + '-\\d+-)');
var replacement = prefix + '-' + ndx + '-';
if ($(el).attr("for")) $(el).attr("for", $(el).attr("for").replace(id_regex,
replacement));
if (el.id) el.id = el.id.replace(id_regex, replacement);
if (el.name) el.name = el.name.replace(id_regex, replacement);
}
function deleteForm(btn, prefix) {
var formCount = parseInt($('#id_' + prefix + '-TOTAL_FORMS').val());
if (formCount > 1) {
// Delete the item/form
$(btn).parents('.item').remove();
var forms = $('.item'); // Get all the forms
// Update the total number of forms (1 less than before)
$('#id_' + prefix + '-TOTAL_FORMS').val(forms.length);
var i = 0;
// Go through the forms and set their indices, names and IDs
for (formCount = forms.length; i < formCount; i++) {
$(forms.get(i)).children().children().each(function() {
updateElementIndex(this, prefix, i);
});
}
} // End if
else {
alert("You have to enter at least one todo item!");
}
return false;
}
function addForm(btn, prefix) {
var formCount = parseInt($('#id_' + prefix + '-TOTAL_FORMS').val());
// You can only submit a maximum of 10 todo items
if (formCount < 10) {
// Clone a form (without event handlers) from the first form
var row = $(".item:first").clone(false).get(0);
// Insert it after the last form
$(row).removeAttr('id').hide().insertAfter(".item:last").slideDown(300);
// Remove the bits we don't want in the new row/form
// e.g. error messages
$(".errorlist", row).remove();
$(row).children().removeClass('error');
// Relabel/rename all the relevant bits
$(row).children().children().each(function() {
updateElementIndex(this, prefix, formCount);
if ( $(this).attr('type') == 'text' )
$(this).val('');
});
// Add an event handler for the delete item/form link
$(row).find('.delete').click(function() {
return deleteForm(this, prefix);
});
// Update the total form count
$('#id_' + prefix + '-TOTAL_FORMS').val(formCount + 1);
} // End if
else {
alert("Sorry, you can only enter a maximum of ten items.");
}
return false;
}
// Register the click event handlers
$("#add").click(function() {
return addForm(this, 'form');
});
$(".delete").click(function() {
return deleteForm(this, 'form');
});
});
</script>
</head>
<body>
<form action="" method="POST">{% csrf_token %}
<div class="section">
{{ todo_list_form.as_p }}
</div>
<h2>Todo Items</h2>
{{ book_formset.management_form }}
{% for form in book_formset.forms %}
<div class="item">
{{ form.as_p }}
<p style=""><a class="delete" href="#">Delete</a></p>
</div>
{% endfor %}
<p><a id="add" href="#">Add another item</a></p>
<input type="submit" value=" Submit " />
</form>
</body>
</html>
但是,当我从显示的形式HTML字段并呈现如下图所示
{% for form in book_formset.forms %}
<div class="item">
<div class="with_name_design">{{ form.name }}</div>
{% if form.name.errors %}
{{form.name.errors}}
{% endif %}
<div class="with_age_design">{{ form.age }}</div>
{% if form.age.errors %}
{{form.age.errors}}
{% endif %}
</div>
{% endfor %}
表单被成功地显示,当我点击了该链接Add another item
的新形式与上述jQuery的产生,当我试图进入所有细节提交并点击提交,这是由jQuery的添加的下一个形式是像显示验证错误name, age is required
?(这是在这种情况下是显示领域seperately代替form.as_p()只发生,如果我们呈现为form.as_p()其工作正常,并记录在创建数据库)
所以,我真的无法弄清楚它为什么当我呈现的形式是succeded form.as_p()
为什么不是我呈现individual fields with their errors
我失去了产生另一种形式的javascript代码高于一切/需要和任何在?
因为当我们单独呈现的字段,通过点击添加其他形式的按钮显示验证错误产生的形式?
我真的浪费了大量的时间搞清楚以上的JavaScript,因为我得到了它的一些地方通过谷歌搜索周围,
所以最后上述functionlality工作当我们在表单集形式form.as_p()
但为什么当我们单独渲染表单字段上述功能无法正常工作?
任何人都可以请让我知道如何解决上述问题(也可能是上面的代码将是有用的形式很多用户动态创建的形式就像我们在Django管理在线表单)
编辑
ķ感谢schillingt,
因此,根据下面的UR答案有我修改的JavaScript和HTML像下面
{% for form in book_formset.forms %}
<div class="item">
<div class="with_name_design">{{ form.name }}</div>
{% if form.name.errors %}
<span>{{form.name.errors.0}}</span>
{% endif %}
<div class="with_age_design">{{ form.age }}</div>
{% if form.age.errors %}
<span>{{form.age.errors.0}}</span>
{% endif %}
</div>
{% endfor %}
和形式已变得与错误后form validation
但我所面临的问题不同,如下
- 当我们点击
Add another item
按钮,一个新的表单已成功创建。 - 而当我们提交的表单与
empty data
时,validation
正确显示相应的提示以下错误消息fields
一个问题
- 现在,当我们尝试
add another form
,以前的所有形式,包括错误消息再次重新显示
就像如果我们有two
的形式,当我们点击submit
没有数据,验证错误消息产生两种形式,现在马上当我们点击Add another item
,共four forms
已经建立,我的意思是以前创建了两个形式被重复包括验证消息
发出两个
- 所以,现在马上当我们试图删除一个形式,我的意思是,当我们点击
delete
表单按钮,所有的形式(如4 forms
在这种情况下)被删除?
所以你怎么能请让我知道如何解决这个问题?